I found weird Hibernate behavior that I can not understand.
Let's say I have class A (was inspired with this question
https://stackoverflow.com/questions/339 ... ntity-type)
@Entity
Code:
public class A {
@Id
private String id;
private String name;
@ManyToOne
@JoinColumn(name = "PARENT")
private A parent;
@OneToMany(mappedBy = "parent",cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE })
private Set<A> children;
// Getters, Setters, etc...
}
Also, say we have Spring JPA Repository
Code:
public interface ARepository extends JpaRepository<A, Long> {}
And test class where magic happens
Code:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:spring/applicationContext-test.xml" })
public class ATest {
@Autowired
private ARepository aRepository;
@Test
public void testA() {
A parent = new A();
parent.setName("I am Parent: 121_1001_21");
parent.setId("121_1001_21");
A son = new A();
son.setName("I am Son: 121_1001_31");
son.setId("121_1001_31");
son.setParent(parent);
A daughter = new A();
daughter.setName("I am Daughter: 121_1001_32");
daughter.setId("121_1001_32");
daughter.setParent(son);
// daughter.setParent(parent);// yes, I'm intentionally creates wrong hierarchy
parent.setChildren(new HashSet<>(Arrays.asList(daughter, son)));// order of elements in set matters!
son.setChildren(new HashSet<>(Arrays.asList(daughter)));
aRepository.save(parent);
}
}
So the hierarchy is following:
Code:
Parent (121_1001_21)
Son (121_1001_31)
Daughter (121_1001_32)
Daughter (121_1001_32)
But this test fails on saving entity with
Code:
javax.persistence.EntityNotFoundException:
Unable to find com.orga.pcom.om.core.entity.productorder.A with id 121_1001_31
After hours of debugging I found that Hibernates tries to load linked entities and load it in this way:
Code:
Parent (121_1001_21) 1st load
Son (121_1001_31) 3rd load (this entity loading is fail!)
Daughter (121_1001_32) 2nd load
Daughter (121_1001_32) 2nd load
and fails! So, the questions are:
Why Hibernate loads something while it saves something? :)
What is the best way to fix this issue?