How to map @OneToOne with Primary key association
jfrankman Sep 21, 2007 4:30 PMI have two classes Client and Drivingdistance with a one to one association. The id of the Client is the PK and FK in DrivingDistance. My mapping annotations are as follows:
Client class:
@Table(name="FBCLIENT") @Name("client") @Scope(ScopeType.SESSION) public class ClientVO implements Serializable { @Id @NotNull @Column(name="CLIENTID") public Long getId() { return id; } @OneToOne(cascade = CascadeType.ALL) @PrimaryKeyJoinColumn() public DrivingDistanceVO getDrivingDistance() { return drivingDistance; } ...}
Driving Distance
@Entity @Table(name="FBDRVDSTNC") @Name("drivingDistance") public class DrivingDistanceVO implements Serializable { @Id @Column(name="CLIENTID") @GeneratedValue(generator="foreign") @GenericGenerator(name="foreign", strategy = "foreign", parameters={ @Parameter(name="property", value="client") }) public Long getId() { return id; } @OneToOne(mappedBy="drivingDistance") public ClientVO getClient() { return client; } }
If I try to assign a driving distance to the client and save it:
ClientVO client=(ClientVO)q.getSingleResult(); DrivingDistanceVO vo2=new DrivingDistanceVO(); //vo2.setId(new Long(225415)); vo2.setLocation1(new Long(48254)); vo2.setLocation2(new Long(171767)); vo2.setUriString("http://www.google.com/intl/en_ALL/images/logo.gif"); if (client.getDrivingDistance()==null) { client.setDrivingDistance(vo2); em.merge(client); }
I get the following error:
javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: client at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:567) at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:210) at com.idfbins.nexus.business.test.ClientDrivingDistanceTest.testClientDriveDistancePersist(ClientDrivingDistanceTest.java:63) Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: client at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:98) at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:165) at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:102) at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:51) at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:679) at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:663) at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:667) at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:201) ... 22 more ... Removed 21 stack frames
I have poured over the documentation and forums but can't understand why this is failing. I have seen others ask similar questions, but have not found any answers. I have noticed that if I call em.persist instead of em.merge I do not get this error. However, I thought that since the client already exists in the database that merge would be the appropriate method to call.
So, can anyone explain why I am getting the message "org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: client
" even after I have assigned the driving distance to the client ( client.setDrivingDistance(vo2);
)