I have the following mapping:
# A Parent {{Post}} entity
{code:java} @Entity(name = "Post") public class Post {
@Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id;
private String name;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "post", optional = false, fetch = FetchType.LAZY) private PostDetails details;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public PostDetails getDetails() { return details; }
public void addDetails(PostDetails details) { this.details = details; details.setPost(this); } } {code}
# A Child {{PostDetails}} entity:
{code:java} @Entity(name = "PostDetails") public class PostDetails {
@Id private Long id;
private Date createdOn;
public PostDetails() { createdOn = new Date(); }
@OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "id") @MapsId private Post post;
public Long getId() { return id; }
public void setPost(Post post) { this.post = post; } } {code}
When I try to cascade the persist operation from Post to PostDetails:
{code:java} Post post = new Post(); post.setName("Hibernate Master Class"); post.addDetails(new PostDetails()); session.persist(post); {code}
I get the following error:
{noformat} org.hibernate.id.IdentifierGenerationException: null id generated for:class com.vladmihalcea.hibernate.masterclass.laboratory.cascade.CascadeLockTest$PostDetails at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:119) at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149) at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794) at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:314) at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350) at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293) at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:432) at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:265) at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194) at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125) at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75) at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789) {noformat}
If I make the association as optional:
{code:java} @OneToOne(cascade = CascadeType.ALL, mappedBy = "post", optional = true, fetch = FetchType.LAZY) {code}
The persist works properly. |
|