Hi, We have the following entity relation ship. User is the parent entity.DistrictUserDetail is the child.
@Entity @Table(name="USERS") public class User implements Serializable {
@Id @Column(name="ID", nullable=false) @GeneratedValue(generator="system-uuid") @GenericGenerator(name="system-uuid", strategy = "uuid") private String id;
@OneToOne(cascade= {CascadeType.ALL}) @PrimaryKeyJoinColumn(name="ID", referencedColumnName="USER_ID") public DistrictUserDetail districtUserDetail;
... other properties..
This is the parent entity. The child entities primary key is a foreign key to User entity, and we have defined its key properties as:
@Entity @Table(name="DISTRICT_USER_DETAIL") public class DistrictUserDetail implements Serializable{
@Id @Column(name="USER_ID") @GeneratedValue(generator="foreign") @GenericGenerator(name="foreign", strategy = "foreign", parameters={@Parameter(name="property",value="user")}) protected String userId;
@OneToOne(mappedBy="districtUserDetail") User user;
... other properties
So, when we create a new User, and create a new DistrictUser, and set the DistrictUser to the User and save User, we expect that the User is saved and due to cascadeAll, DistrictUser is also saved.
This is our test:
public void testSaveUserWithDistrictUserDetails() throws Exception { User user = new User(); user.setFirstName("John"); user.setLastName("Doe"); user.setUserName("U11111");
DistrictUserDetail userDetail = new DistrictUserDetail();
userDetail.setIsLoginAllowed(Boolean.TRUE); userDetail.setIsSuperintendent(Boolean.TRUE);
user.setDistrictUserDetail(userDetail);
User newUser = dao.save(user);
assertTrue(newUser!=null); assertTrue(newUser.getId()!=null); }
But we encounter the following hibernate exception:
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: user at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:44) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:99) at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:315) at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:283) at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:238) at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:688) at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:670) at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245) at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:269) at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:217) at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:170) at org.hibernate.engine.Cascade.cascade(Cascade.java:131) at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456) at org.hibernate.event.def.DefaultMergeEventListener.mergeTransientEntity(DefaultMergeEventListener.java:352) at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:283) at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:238) at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85) at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:678) at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:662) at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:666) at org.springframework.orm.hibernate3.HibernateTemplate$23.doInHibernate(HibernateTemplate.java:817) at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406) ... 49 more
Is there a way to make this bi-directional oneToOne relationship work? If not does hibernate provide any alternatives?
|