I have two entities with @OneToOne relationship:
@Entity
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user")
private Long id;
@OneToOne(cascade = CascadeType.MERGE, orphanRemoval=true)
@JoinColumn(name = "id_details")
private UserDetails details;
//...username, password, email
}
@Entity
public class UserDetails implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user_details")
private Long id;
//...firstname, lastname, address
}
First of all I save User with UserDetails:
public class Main {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
UserDetails details = new UserDetails("John", "Doe", "NYC 11");
User user = new User("uname", "pass", "mail", details);
em.merge(user);
em.getTransaction().commit();
em.close();
emf.close();
}
}
Everything works fine, since there is cascade MERGE, so both entities are saved. When I run another class:
public class MainUpdate {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
EntityManager em = emf.createEntityManager();
User user = em.find(User.class, 1L);
user.setDetails(null);
em.getTransaction().begin();
em.merge(user);
em.getTransaction().commit();
em.close();
emf.close();
}
}
I expected that id_details in user will be set to null in the database (and it is) but since there is orphanRemoval=true I also expected that the orphan row will be removed from userdetails table but it is not.
What is interesting when I set the CascadeType PERSIST instead of MERGE the orphan is removed. Can someone explain why PERSIST works with orphanRemoval but MERGE does not?
GitHub repo: https://github.com/slwch/onetoone-orphan
Tested with Hibernate 5.0.6 and 4.1.8