org.hibernate.LazyInitializationException: konnte nicht initialisiert proxy - keine Sitzung, encore un fois
Foo aussieht, hat dieser in es :
@ManyToMany
private Set<User> favouritedBy;
während der Benutzer ist das:
@ManyToMany(mappedBy = "favouritedBy")
private Set<Foo> favourites = new HashSet<Foo>();
public Set<Foo> getFavourites() {
return favourite;
}
Und fooService hat dies mit der lazyloaded Sammlung zugegriffen wird, während die Sitzung wird geöffnet, über das tranactional Methode :
@Transactional(readOnly = true)
public Set<Foo> getFavourites(User user) {
user = dao.get(User.class, user.getId()); //the dao gets a session
Set<Foo> favourites = user.getFavourites();//but the session is not here and the exception is thrown?
return favourties;
}
BEARBEITEN
So behebt man es, ohne die Verwendung von Kriterien :
Set<Foo> favourites = new HashSet<Foo>(user.getFavourites());
und so behebt man es mit den Kriterien
Session session = sessionFactory.getCurrentSession();
final Criteria crit = session.createCriteria(Foo.class);
crit.setFetchMode("favourites", FetchMode.JOIN);
crit.add(Property.forName("id").eq(id));
return (Foo) crit.uniqueResult();
- sind Sie sicher, dass Sie
transactionManager
im Frühjahr Kontext undtx:annotation-driven
definiert? - ja, alles funktioniert ok, auch sonst überall ...
- kannst du den stack-trace hier? wir werden prüfen, ob Transaktions-handling-code ist es
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Standard -
FetchType
in einemManyToMany
istLAZY
und der hibernate-Dokumentation für arbeiten mit faul Verbände klar fordert heraus, diese Art von Zugang als ein Fehler. Sie können interagieren mit träge zugehörigen Objekte erst während der Sitzung ist noch offen. Dieser Teil der Dokumentation bietet auch alternativen für den Zugang zu solchen faul assoziierte Mitglieder eines Objekts . Wir bevorzugen den fetch-Modus anzugeben, wieJOIN
die Kriterien, die in unseren AnwendungenBearbeiten:
Die obige Aussage eigentlich nicht zurückgeben set enthält alle
Foo
Objekte. Es ist nur ein proxy. Die tatsächlicheFoo
Objekte abgerufen werden, nur wenn die Elemente in den Satz zugegriffen werden, wiefavorites.iterator()
etc., Dieser Vorgang ist eindeutig geschehen außerhalb IhresgetFavorites()
Methode. Aber die@Transactional
annotation auf dergetFavorites()
Methode zeigt an, dass die Sitzung geschlossen am Ende dieser Methode.So, wenn Methoden aufgerufen werden, die auf den Favoriten gesetzt, die session ist bereits geschlossen und damit die Ausnahme.
Diese Adresse verwenden, sollten Sie das Kriterien-Objekt zum abrufen der Benutzer und festlegen des fetch-Typs als
JOIN
so, dass die Foo-Objekte bewohnt werden, die im User-Objekt zurückgegeben.getFavorites()
Methode, wäre die session bereits geschlossen, da der Umfang der Transaktion endet mit dem Ende dergetFavorites()
Methode.user.getFavorites()
- Methode nicht mit einer gültigen Sitzung, um Sie zu Holen aus dem datenspeicher.Gibt es zwei Lösungen.
Nicht verwenden lazy load.
Set
lazy=false
im XML-oder im Set@OneToMany(fetch = FetchType.EAGER)
In annotation.Verwenden lazy load.
Set
lazy=true
im XML-oder im Set@OneToMany(fetch = FetchType.LAZY)
In annotation.und fügen Sie filter in Ihrem
web.xml
Sowie
<param-value>mySessionFactory</param-value>
ist Ihre sessionFacory bean-Namen, definiert inapplicationContext.xml
Ja, das Objekt zugegriffen werden soll, im transnationalen Kontext sonst wird es werfen eine
LazyInitializationException
.