Hi
I am quite new to Vaadin and JPAContainer (using EclipseLink) and I am having a problem I could not resolve. I will start explaining the entities I have and its relations:
- User
- Company
- CompanyAssignment
User has a list of CompanyAssignment, and CompanyAssignment has a field “role”, “company” and user. Here are entities:
@Entity
public class User {
@NotNull
@Column(unique = true)
@Size(min = 4, max = 16)
private String username;
@NotNull
@Size(min = 4)
private String password;
private Boolean active;
@NotNull
@Size(max = 255)
private String name;
@OneToMany(mappedBy="user", cascade={CascadeType.MERGE}, orphanRemoval=true)
private List<CompanyAssignment> company;
//Getters and setters
}
@Entity
public class Company {
@Size(max = 255)
private String name;
@OneToMany(mappedBy="company", cascade={CascadeType.MERGE})
private List<CompanyAssignment> users;
//Getters and setters
}
@Entity
@IdClass(CompanyAssignmentId.class)
public class CompanyAssignment {
@Id
@ManyToOne
@JoinColumn(name="COMPANY_ID", insertable=true, updatable=false)
private Company company;
@Id
@ManyToOne
@JoinColumn(name="USER_ID", insertable=true, updatable=false)
private User user;
@NotNull
@Enumerated(EnumType.STRING)
@Column(name="ROLE", insertable=true, updatable=true)
private CompanyRoles role;
//Getters and setters
}
//Not an Entity
public class CompanyAssignmentId implements Serializable {
private Long company;
private Long user;
public Long getCompany() {
return company;
}
public void setCompany(Long company) {
this.company = company;
}
public Long getUser() {
return user;
}
public void setUser(Long user) {
this.user = user;
}
}
So CompanyAssignment entity’s ID are composed by two PK.
Now I want to make an User administration page consisting on a User table and a Form. When the user clicks a row the Form appears with data to edit. The problem is User entity’s Company field representation. I am using a CustomField make of a Table with only two columns: one for the Company name (nested field “company.name”) and a ComboBox (using an inherited DefaultFieldFactory to display it).
In the User Table I am using a JPAContainerFactory.make(). When clicking a row I pass the EntityItem to the Form. In the form I call setItemDataSource to set the item and using a DefaultFieldFactory I create a CompanyAssignmentTable which extend CustomField.
In this CustomField I create a BeanItemContainer (or BeanContainer<CompanyAssignmentId,CompanyAssignment>) and override setPropertyDataSource method to add all beans to the container.
On the Form I have an apply button which calls Form.Commit() method.
All data displays correctly, but when clicking on Commit button in the Form I get an EclipseLink error unable to update primray key columns.
[EL Warning]
: 2012-02-02 11:20:51.814--UnitOfWork(1454176402)--Thread(Thread[http-8080-2,5,main]
)--Exception [EclipseLink-7251]
(Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [user]
of class [com.myproject.domain.CompanyAssignment]
is mapped to a primary key column in the database. Updates are not allowed.
2012-02-02 11:20:51,815 [http-8080-2]
com.myproject.web.ui.panels.admin.FormUser$1.buttonClick(FormUser.java:94) ERROR - Unable to save user
com.vaadin.data.Buffered$SourceException
at com.vaadin.ui.Form.commit(Form.java:365)
at com.myproject.web.ui.panels.admin.FormUser$1.buttonClick(FormUser.java:86)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:512)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:164)
at com.vaadin.ui.AbstractComponent.fireEvent(AbstractComponent.java:1219)
at com.vaadin.ui.Button.fireClick(Button.java:550)
at com.vaadin.ui.Button.changeVariables(Button.java:217)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.changeVariables(AbstractCommunicationManager.java:1451)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariableBurst(AbstractCommunicationManager.java:1399)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1318)
at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:763)
at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:296)
at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
Caused by: com.vaadin.data.Buffered$SourceException
at org.vaadin.addon.customfield.CustomField.commit(CustomField.java:186)
at com.myproject.web.ui.panels.admin.CompanyAssignmentTable.commit(CompanyAssignmentTable.java:237)
at com.vaadin.ui.Form.commit(Form.java:339)
... 29 more
Caused by: com.vaadin.data.Property$ConversionException: javax.persistence.PersistenceException: Exception [EclipseLink-7251]
(Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [user]
of class [com.myproject.domain.CompanyAssignment]
is mapped to a primary key column in the database. Updates are not allowed.
at com.vaadin.addon.jpacontainer.JPAContainerItem$ItemProperty.setValue(JPAContainerItem.java:289)
at org.vaadin.addon.customfield.CustomField.commit(CustomField.java:180)
... 31 more
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-7251]
(Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [user]
of class [com.myproject.domain.CompanyAssignment]
is mapped to a primary key column in the database. Updates are not allowed.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:747)
at com.vaadin.addon.jpacontainer.provider.MutableLocalEntityProvider$4.run(MutableLocalEntityProvider.java:208)
at com.vaadin.addon.jpacontainer.provider.MutableLocalEntityProvider.runInTransaction(MutableLocalEntityProvider.java:117)
at com.vaadin.addon.jpacontainer.provider.MutableLocalEntityProvider.updateEntityProperty(MutableLocalEntityProvider.java:194)
at com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider.updateEntityProperty(CachingMutableLocalEntityProvider.java:185)
at com.vaadin.addon.jpacontainer.JPAContainer.containerItemPropertyModified(JPAContainer.java:1186)
at com.vaadin.addon.jpacontainer.JPAContainerItem$ItemProperty.setValue(JPAContainerItem.java:282)
... 32 more
Caused by: Exception [EclipseLink-7251]
(Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [user]
of class [com.myproject.domain.CompanyAssignment]
is mapped to a primary key column in the database. Updates are not allowed.
at org.eclipse.persistence.exceptions.ValidationException.primaryKeyUpdateDisallowed(ValidationException.java:2393)
at org.eclipse.persistence.mappings.OneToOneMapping.writeFromObjectIntoRowWithChangeRecord(OneToOneMapping.java:1710)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildRowForUpdateWithChangeSet(ObjectBuilder.java:1206)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.updateObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:1126)
at org.eclipse.persistence.queries.UpdateObjectQuery.executeCommitWithChangeSet(UpdateObjectQuery.java:84)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:291)
at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:808)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:711)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2842)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1521)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1503)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1463)
at org.eclipse.persistence.internal.sessions.CommitManager.commitChangedObjectsForClassWithChangeSet(CommitManager.java:265)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:128)
at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3766)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1404)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:616)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1552)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:427)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:744)
... 38 more
So it seems JPAContainer is trying to update user field in CompanyAssignment, but I have not made any changes to it (only to role field). Is there any way to make user and company field in CompanyAssignment not be written to DB?