615 Stimmen

Hibernate löst MultipleBagFetchException aus - kann nicht gleichzeitig mehrere Beutel abrufen

Hibernate löst diese Ausnahme bei der Erstellung der SessionFactory aus:

org.hibernate.loader.MultipleBagFetchException: kann nicht mehrere Taschen gleichzeitig abrufen

Dies ist mein Testfall:

Elternteil.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;

}

Kind.java

@Entity
public Child {

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

 @ManyToOne
 private Parent parent;

}

Was ist mit diesem Problem? Was kann ich tun?


EDITAR

OK, das Problem, das ich habe, ist, dass eine andere "übergeordnete" Entität innerhalb meiner übergeordneten ist, mein wirkliches Verhalten ist dies:

Elternteil.java

@Entity
public Parent {

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

 @ManyToOne
 private AnotherParent anotherParent;

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

}

AnotherParent.java

@Entity
public AnotherParent {

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

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

}

Hibernate mag keine zwei Sammlungen mit FetchType.EAGER aber das scheint ein Fehler zu sein, ich mache keine ungewöhnlichen Dinge...

Entfernen von FetchType.EAGER de Parent o AnotherParent löst das Problem, aber ich brauche es, also ist die wirkliche Lösung die Verwendung von @LazyCollection(LazyCollectionOption.FALSE) anstelle von FetchType (Dank an Bozho für die Lösung).

2 Stimmen

Ich würde fragen, welche SQL-Abfrage Sie zu erstellen hoffen, die zwei separate Sammlungen gleichzeitig abruft? Die Arten von SQL, mit denen dies möglich wäre, würden entweder eine kartesische Verknüpfung (potenziell höchst ineffizient) oder eine UNION disjunkter Spalten (ebenfalls hässlich) erfordern. Vermutlich hat die Unfähigkeit, dies in SQL auf eine saubere und effiziente Weise zu erreichen, das API-Design beeinflusst.

0 Stimmen

@ThomasW Dies sind die Sql-Abfragen, die das Programm generieren sollte: select * from master; select * from child1 where master_id = :master_id; select * from child2 where master_id = :master_id

2 Stimmen

Ein ähnlicher Fehler kann auftreten, wenn Sie mehr als eine List<child> con fetchType definiert für mehr als eine List<clield>

1voto

Für mich bestand das Problem darin, dass ich verschachtelte EAGER holt.

Eine Lösung besteht darin, die verschachtelten Felder auf LAZY und verwenden Sie Hibernate.initialize(), um das/die verschachtelte(n) Feld(er) zu laden:

x = session.get(ClassName.class, id);
Hibernate.initialize(x.getNestedField());

1voto

JAD Punkte 970

Bei mir trat dies auf, wenn ich mehrere Sammlungen mit FetchType.EAGER hatte, wie hier:

@ManyToMany(fetch = FetchType.EAGER, targetEntity = className.class)
@JoinColumn(name = "myClass_id")
@JsonView(SerializationView.Summary.class)
private Collection<Model> ModelObjects;

Außerdem wurden die Sammlungen auf derselben Säule zusammengeführt.

Um dieses Problem zu lösen, änderte ich eine der Sammlungen auf FetchType.LAZY, da dies für meinen Anwendungsfall in Ordnung war.

Viel Glück! ~J

1voto

alxkudin Punkte 11

Sie können auch versuchen, fetch=FetchType.LAZY zu machen und einfach @Transactional(readOnly = true) zu der Methode hinzuzufügen, in der Sie Child erhalten

0voto

prisar Punkte 2809

Kommentar zu beiden Fetch y LazyCollection hilft manchmal bei der Durchführung von Projekten.

@Fetch(FetchMode.JOIN)
@LazyCollection(LazyCollectionOption.FALSE)

0voto

WesternGun Punkte 9127

Eine gute Sache über @LazyCollection(LazyCollectionOption.FALSE) ist, dass mehrere Felder mit diesem Vermerk nebeneinander bestehen können, während FetchType.EAGER nicht, auch nicht in den Fällen, in denen eine solche Koexistenz rechtmäßig ist.

Zum Beispiel kann ein Order kann eine Liste von OrderGroup (eine kurze) sowie eine Liste von Promotions (auch kurz). @LazyCollection(LazyCollectionOption.FALSE) kann für beide verwendet werden, ohne dass es zu LazyInitializationException weder MultipleBagFetchException .

In meinem Fall @Fetch hat mein Problem gelöst, dass MultipleBacFetchException verursacht dann aber LazyInitializationException die berüchtigte no Session Fehler.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X