|
Given a bidirectional @OneToOne relationship between Parent and Child Entity:
@Entity
public class Parent {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Long id;
@OneToOne(optional = false, mappedBy = "parent", cascade = ALL)
private Child child;
...
}
@Entity
public class Child {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Long id;
@OneToOne(optional=false)
@JoinColumn(nullable=false)
private Parent parent;
...
}
The following test fails with org.hibernate.PropertyValueException: not-null property references a null or transient value: frol.Child.parent
@Test
public void deleteTest() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("onetone");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Parent a = new Parent();
Child b = new Child();
a.setChild(b);
b.setParent(a);
em.persist(a);
em.flush();
em.clear();
a = em.find(Parent.class, a.getId());
em.remove(a);
em.flush(); }
See also the test case on GitHub.
I didn't find in JPA spec any restrictions on this kind of association.
Technically this kind of association can be persisted because the foreign key is on child side: first the persistence provider could delete the child and then its parent. But at runtime the deletion order seems to be different.
I found the following workarounds:
-
mark one end of the association as optional
-
make the association unidirectional
I use Hibernate 4.3.6.Final.
The problem also with Hibernate 4.1.5.Final but the exception is different. In this version Hibernate tries first to update the foreign key. Setting it to null causes ConsraintViolation because it is not nullable.
|