Hibernate nie może jednocześnie pobierać wielu worków

Hibernate wyrzuca ten wyjątek podczas tworzenia SessionFactory:

Org.hibernacja.ładowacz.MultipleBagFetchException: nie można pobrać jednocześnie wielu toreb]}

To mój testowy przypadek:

Rodzic.java

@Entity
public Parent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 // @IndexColumn(name="INDEX_COL") if I had this the problem solve but I retrieve more children than I have, one child is null.
 private List<Child> children;

}

Dziecko.java

@Entity
public Child {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @ManyToOne
 private Parent parent;

}

A co z tym problemem? Co mogę zrobić?


EDIT

OK, problem, który mam jest to, że inny" rodzic " istota jest wewnątrz mojego rodzica, mój prawdziwe zachowanie jest takie:

Rodzic.java

@Entity
public Parent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @ManyToOne
 private AntoherParent anotherParent;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 private List<Child> children;

}

Kolejny rodzic.java

@Entity
public AntoherParent {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;

 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 private List<AnotherChild> anotherChildren;

}

Hibernate nie lubi dwóch kolekcji z FetchType.EAGER, ale to chyba błąd, nie robię niezwykłych rzeczy...

Usunięcie FetchType.EAGER z Parent lub AnotherParent rozwiązuje problem, ale potrzebuję go, więc prawdziwym rozwiązaniem jest użycie @LazyCollection(LazyCollectionOption.FALSE) zamiast FetchType (dzięki Bozho za rozwiązanie).

Author: Community, 2010-12-02

11 answers

Myślę, że nowsza wersja hibernate (obsługująca JPA 2.0) powinna sobie z tym poradzić. Ale poza tym możesz to obejść, adnotując pola kolekcji za pomocą:

@LazyCollection(LazyCollectionOption.FALSE)

Pamiętaj, aby usunąć atrybut fetchType z adnotacji @*ToMany.

Ale zauważ, że w większości przypadków {[3] } jest bardziej odpowiedni niż List<Child>, więc jeśli naprawdę nie potrzebujesz List - idź do Set

 424
Author: Bozho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-11 07:45:46

Po prostu zmień typ z List Na typ Set.

 230
Author: Ahmad Zyoud,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-16 11:25:08

Alternatywnie dodaj adnotację @Fetch specyficzną dla Hibernatu do kodu:

@OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
private List<Child> childs;

Powinno to rozwiązać problem związany z błędem Hibernate HHH-1718

 87
Author: DaveRlz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-18 11:04:42

Po wypróbowaniu każdej opcji opisanej w tym postach i innych, doszedłem do wniosku, że poprawka jest następująca.

In every xtomany place @XXXToMany(mappedBy="parent", fetch=FetchType.EAGER) i pośrednio po

@Fetch(value = FetchMode.SUBSELECT)

To zadziałało dla mnie

 21
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-27 16:46:14

Aby to naprawić, po prostu weź Set w miejsce List dla zagnieżdżonego obiektu.

@OneToMany
Set<Your_object> objectList;

I nie zapomnij użyć fetch=FetchType.EAGER

To zadziała.

Jest jeszcze jedna koncepcja CollectionId w Hibernate, jeśli chcesz trzymać się tylko listy.

 18
Author: Prateek Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-16 11:28:15

Znalazłem dobry wpis na blogu o zachowaniu Hibernate w tego typu mapowaniach obiektów: http://blog.eyallupu.com/2010/06/hibernate-exception-simultaneously.html

 10
Author: Christian Müller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-11 15:52:34

Możesz zachować listy Bootha w JPA i dodać do co najmniej jednej z nich adnotację JPA @ OrderColumn (Oczywiście z nazwą pola do zamówienia). Nie ma potrzeby stosowania konkretnych adnotacji hibernate. Należy jednak pamiętać, że może tworzyć puste elementy na liście, jeśli wybrane pole nie ma wartości zaczynających się od 0

 [...]
 @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
 @OrderColumn(name="orderIndex")
 private List<Child> children;
 [...]

W przypadku dzieci należy dodać pole orderIndex

 4
Author: Massimo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-25 09:29:18

Powodem, dla którego dostajesz ten wyjątek jest to, że Hibernate skończyłby robiąc produkt kartezjański, który jest zły dla wydajności.

Teraz, chociaż możesz" naprawić " problem używając Set zamiast List, nie powinieneś tego robić, ponieważ produkt kartezjański nadal będzie opisywany w podstawowych instrukcjach SQL.

Lepiej jest przełączyć się z FetchType.EAGER na Fetchype.LAZY, ponieważ eager fetching jest okropnym pomysłem, który może prowadzić do krytycznej wydajności aplikacji issues .

Jeśli chcesz pobrać jednostki potomne w wielopoziomowej hierarchii, lepiej wybierz od najbardziej wewnętrznego dziecka do rodziców, Jak wyjaśniono w tym artykule .

 3
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-27 06:01:16

Jeśli masz zbyt złożone obiekty z kolekcją saveral nie może być dobrym pomysłem, aby mieć wszystkie z nich z EAGER fetchType, lepiej Użyj LAZY i kiedy naprawdę trzeba załadować Kolekcje użyj: Hibernate.initialize(parent.child) aby pobrać dane.

 1
Author: Felipe Cadena,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-15 13:38:21

Próbowaliśmy ustawić zamiast List i jest to koszmar: po dodaniu dwóch nowych obiektów, równa się() i hashCode () nie rozróżnia obu z nich ! Bo nie mają dokumentów.

Typowe narzędzia takie jak Eclipse generują taki kod z tabel bazy danych:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    return result;
}

Możesz również przeczytać ten artykuł , który wyjaśnia, jak pojebane jest JPA/Hibernate. Po przeczytaniu tego, myślę, że to ostatni raz, Kiedy używam jakiegokolwiek ORM w moim życie.

Spotkałam również facetów z Domain Driven Design, którzy w zasadzie mówią, że ORM to straszna rzecz.

 0
Author: Mike Dudley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 13:52:56

Możesz użyć nowej adnotacji, aby rozwiązać ten problem:

@XXXToXXX(targetEntity = XXXX.class, fetch = FetchType.LAZY)

W rzeczywistości domyślną wartością fetch jest FetchType.Leniwy też.

 -2
Author: leee41,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 03:26:41