Mam ten problem od dłuższego czasu, przeszukałem sieć i SO i obecnie i nie znalazłem jeszcze rozwiązania. Mam nadzieję, że możesz mi w tym pomóc.Hibernate @OneToMany z mappedBy (rodzic-dziecko) relacja i problem z pamięcią podręczną
Mam relacji rodzic-dziecko pomiędzy dwoma podmiotami, jak następuje:
@Entity
public class Parent {
// ...
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private Set<Child> children = new HashSet<Child>();
// ...
}
@Entity
public class Child {
// ...
@ManyToOne(fetch = FetchType.LAZY)
private Parent parent;
// ...
}
Rzeczą jest, że gdy tworzę nowe dziecko i przypisać go do rodzica, rodzic nie jest aktualizowany, gdy jest już w pamięci podręcznej.
Parent parent = new Parent();
em.persist(parent);
// ...
Child child = new Child();
child.setParent(parent);
em.persist(child);
parent.getChildren().size(); // returns 0
Próbowałem użyć @PreUpdate aby automatycznie dodać dziecka do rodzica, gdy dziecko jest zachowywane, ale w przypadku, gdy mamy 2 menedżerów podmiotem w 2 różnych wątków (jak w JBoss), problem nadal istnieje, dopóki nie zadzwonimy pod numer em.refresh(parent)
Pytanie brzmi - czy istnieje sposób na płynne wyeliminowanie problemu i zapewnienie, że parent.getChildren()
zawsze zwraca aktualną listę dzieci?
Dziękujemy za obszernej odpowiedzi, Michael. Znalazłem w nim dobre informacje. Obawiam się jednak, że nie rozwiązuje problemu, który mam, ponieważ dwie różne instancje EntityManager przechowują dwie różne pamięci podręczne, a gdy jedna z nich aktualizuje instancję jednostki, druga nie widzi aktualizacji, a jej obiekt w pamięci podręcznej staje się nieaktualny. – artemb
Wygląda na to, że musisz spojrzeć na wyzwalacze aktualizacji, które następnie wezmą ten obiekt i zaktualizują inną pamięć podręczną. Lub możesz uczynić te dwa elementy pamięci podręcznej członkami tego samego klastra, jeśli buforujesz rozwiązanie wspomagające tworzenie klastrów. –
Niestety nie mam kontroli nad pamięcią podręczną sesji Hibernate. A może ja? – artemb