I have the following structure in my project:
public class A {
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST,
org.hibernate.annotations.CascadeType.REFRESH, org.hibernate.annotations.CascadeType.MERGE})
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "a_id")
private List<B> bs;
}
public class B {
@Cascade(org.hibernate.annotations.CascadeType.ALL)
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "b_id")
private C c;
}
public class C {
@ManyToMany(fetch = FetchType.EAGER, targetEntity = TjenesteFraIN.class,
cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinTable(name = "c_d",
joinColumns = @JoinColumn(name = "c_id"),
inverseJoinColumns = @JoinColumn(name = "d_id"))
private List<D> ds;
}
public class D {
...
}
Then, a scenerio where I have a detached A-object, with a reference to a detached B-object, which in turn has a reference to a detached C-object, which has references to a couple of D-objects. (I'm using JMS, so they are really really detached). Like this:
final A a = getA(123); //load A-object from database
final C c = a.getSpecialC();
c.addD(getD(1)); //get Ds from database
c.addD(getD(2));
//Serialize A and send JMS-call to store the A
//On the other side, deserialize A, and then call
public A mergeA(final A a) {
return getSession(false).merge(a);
}
Now, the detached A will be merged with the database representation of the A, the same for B and C, but what will happen with the new referenced from the C to the Ds? I'm seeing in practice that it does not work, nothing is stored in the c_d connection table, but i don't understand why. Is it due to limitations in Hibernate/JPA, or am I missing something with regards to my configuration?
Update:
By using the debugger, I was able to an explicit getSession().merge() on the C-object, and then it's references to D got stored in the database. Still don't quite get why Hibernate cascade won't take care of this for me, but will keep digging.