I couldn't find a way to attach the project to this reply; but here is the test case:
class A has bidirectional one-to-many relationship to classes B1, B2, B3, B4
(b1List, b2List, b3List, b4List)
B1 has bidirectional one-to-many relationship to C1
(c1List)
B2 has bidirectional one-to-many relationship to C2
(c2List)
as follows:
Code:
package com.test.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.OptimisticLockType;
@Entity
@AccessType("field")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@org.hibernate.annotations.Entity(optimisticLock=OptimisticLockType.VERSION)
public class A {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
@OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
private Set<B1> b1List;
@OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
private Set<B2> b2List;
@OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
private Set<B3> b3List;
@OneToMany(fetch = FetchType.LAZY, mappedBy="a", cascade = {CascadeType.PERSIST})
private Set<B4> b4List;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Set<B1> getB1List() {
if(b1List == null)
b1List = new HashSet<B1>();
return b1List;
}
public void setB1List(Set<B1> list) {
b1List = list;
}
public Set<B2> getB2List() {
if(b2List == null)
b2List = new HashSet<B2>();
return b2List;
}
public void setB2List(Set<B2> list) {
b2List = list;
}
public Set<B3> getB3List() {
return b3List;
}
public void setB3List(Set<B3> list) {
if(b3List == null)
b3List = new HashSet<B3>();
b3List = list;
}
public Set<B4> getB4List() {
return b4List;
}
public void setB4List(Set<B4> list) {
if(b4List == null)
b4List = new HashSet<B4>();
b4List = list;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Code:
package com.test.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import org.hibernate.annotations.AccessType;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.OptimisticLockType;
@Entity
@AccessType("field")
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
@org.hibernate.annotations.Entity(optimisticLock=OptimisticLockType.VERSION)
public class B1 {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST})
@JoinColumn(name = "aId")
private A a;
@OneToMany(fetch = FetchType.LAZY, mappedBy="b1", cascade = {CascadeType.PERSIST})
private Set<C1> c1List;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public Set<C1> getC1List() {
if(c1List == null)
c1List = new HashSet<C1>();
return c1List;
}
public void setC1List(Set<C1> list) {
c1List = list;
}
}
(other classes are just the same, so I don't copy their code here)
I have entered data in quite all of the tables.
Now, when I run the following code which finds an object of type A, and in its b2List finds an object of type B2, and then adds a C2 to this B2 and persists the C2:
Code:
A a = em.find(A.class, 1);
C2 c2 = new C2();
for(B2 b2:a.getB2List())
{
if(b2.getId() == 1)
{
b2.getC2List().add(c2);
c2.setB2(b2);
}
}
em.persist(c2);
Here is what I will see after the line em.persist(c2) is executed:
Code:
16:08:32,296 INFO [STDOUT] Hibernate: select a0_.id as id0_0_, a0_.name as name0_0_ from A a0_ where a0_.id=?
16:08:32,375 INFO [STDOUT] Hibernate: select b2list0_.aId as aId1_, b2list0_.id as id1_, b2list0_.id as id2_0_, b2list0_.aId as aId2_0_ from B2 b2list0_ where b2list0_.aId=?
16:08:32,390 INFO [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,421 INFO [STDOUT] Hibernate: select b1list0_.aId as aId1_, b1list0_.id as id1_, b1list0_.id as id1_0_, b1list0_.aId as aId1_0_ from B1 b1list0_ where b1list0_.aId=?
16:08:32,437 INFO [STDOUT] Hibernate: select c1list0_.b1Id as b2_1_, c1list0_.id as id1_, c1list0_.id as id5_0_, c1list0_.b1Id as b2_5_0_ from C1 c1list0_ where c1list0_.b1Id=?
16:08:32,453 INFO [STDOUT] Hibernate: select c1list0_.b1Id as b2_1_, c1list0_.id as id1_, c1list0_.id as id5_0_, c1list0_.b1Id as b2_5_0_ from C1 c1list0_ where c1list0_.b1Id=?
16:08:32,453 INFO [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,453 INFO [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,453 INFO [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,453 INFO [STDOUT] Hibernate: select c2list0_.b2Id as b2_1_, c2list0_.id as id1_, c2list0_.id as id6_0_, c2list0_.b2Id as b2_6_0_ from C2 c2list0_ where c2list0_.b2Id=?
16:08:32,468 INFO [STDOUT] Hibernate: select b3list0_.aId as aId1_, b3list0_.id as id1_, b3list0_.id as id3_0_, b3list0_.aId as aId3_0_ from B3 b3list0_ where b3list0_.aId=?
16:08:32,468 INFO [STDOUT] Hibernate: select b4list0_.aId as aId1_, b4list0_.id as id1_, b4list0_.id as id4_0_, b4list0_.aId as aId4_0_ from B4 b4list0_ where b4list0_.aId=?
16:08:32,531 INFO [STDOUT] Hibernate: insert into C2 (b2Id) values (?)
The question is, if I am persisting C2, why is it initializing C1 or B4, or other existing C2's?
In our application as the relationships are more complicated and there is a lot of data, this will result in a timeout, so that in some cases it never reaches the very last line (insert).
Thanks for your time