Reputation: 101
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
If User entity can invoke the save of DistrictUserDetail, then why can't DistrictUserDetail see the parent User (and its new id) and use it to save it.
We are using the hibernate version:3.2.7.ga Underlying database is : MySQL
Any help will be appreciated. Thanks
Upvotes: 1
Views: 3575
Reputation: 11
You should set optional attribute of OneToOne to false like this:
@OneToOne(mappedBy="districtUserDetail", optional = false)
User user;
And also, you should set DistrictUserDetail.user to a not-null entity of course.
Upvotes: 1
Reputation: 38816
userDeatil.user
is null
, which is what the exception is complaining about.
I would suggest removing the property and not having a bi-directional relationship. Otherwise, user.setDistrictUserDetail()
also needs to set the user
property.
Upvotes: 1