I have two entities Post and PostDetails that are mapped as OneToOne with shared primary key, optional=false and id generator strategy set as IDENTITY/AUTO. When I try to persist the Post entity it fails with throwing exception.
Assuming we have following entities Post and PostDetails mapped as OneToOne with shared primary key, optional=false and id generator strategy set as IDENTITY/AUTO as below
{code:java} @Entity public class Post implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @OneToOne(mappedBy="post", cascade = { CascadeType.ALL }, optional=false) private PostDetails details; public long getId() { return id; } public PostDetails getDetails() { return details; } public void addDetails(PostDetails details) { this.details = details; details.setPost(this); }
public void deleteDetails() { if(details !=null) { details.setPost(null); } this.details = null; } }
@Entity public class PostDetails implements Serializable { @Id @Column private long id; @OneToOne @JoinColumn(name="id") @MapsId private Post post; public long getId() { return id; } public Post getPost() { return post; } public void setPost(Post post) { this.post = post; } }
{code}
When we execute the following test case to save the entities,
{code:java} @Test public void persistPost() { Session session = sf.getCurrentSession(); session.getTransaction().begin(); Post post = new Post(); PostDetails details = new PostDetails(); post.addDetails(details); session.persist(post); session.beginTransaction().commit(); } {code}
It fails to save and throws the following exception:
{code:java} org.hibernate.id.IdentifierGenerationException: null id generated for:class PostDetails {code} for IDENTITY and {code:java} org.hibernate.exception.ConstraintViolationException: could not execute statement {code} for AUTO
The same code works with both IDENTITY/AUTO if we change it to optional=true as below.
{code:java} Changing @OneToOne(mappedBy="post", cascade = { CascadeType.ALL }, optional=false) to @OneToOne(mappedBy="post", cascade = { CascadeType.ALL }, optional=true) {code}
Although I tested only with DerbyDB and h2, I believe, issue can be replicated on other databases as well. |
|