Heute habe ich mit dem nächsten Problem im Winterschlaf konfrontiert:
Meine Methode:
@Transactional
public Period getDefault(Team team) {
Period defaultPeriod = team.getDefaultPeriod();
List<Period> periods = _periodDAO.getPeriods(team);
if (!periods.contains(defaultPeriod)) {
defaultPeriod = periods.get(periods.size() - 1);
}
}
_periodDAO.initializeIssues(defaultPeriod);
return defaultPeriod;
}
Methode initializeIssues:
public void initializeIssues(Period period) {
if (period.getIssues() != null) {
Hibernate.initialize(period.getIssues());
}
}
Ich erhalte eine Ausnahme bei der Sammlung Perioden enthält defaultPeriod
Caused by: org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:474)
at org.hibernate.Hibernate.initialize(Hibernate.java:417)
Aber wenn ich einige Zeilen entfernen und Methode zu ändern
@Transactional
public Period getDefault(Team team) {
Period defaultPeriod = team.getDefaultPeriod();
_periodDAO.initializeIssues(defaultPeriod);
return defaultPeriod;
}
Es funktioniert gut.
Ich debuggte zuerst Beispiel und Hibernate-Sitzung wird während der gesamten Methode nicht geschlossen.
Wie ich verstehe, wenn geladenes Objekt (ein Element in Perioden) in der Sitzung hat Sammlung, die aktive Sitzung zugeordnet und vor Objekt (defaultPeriod) hat auch die gleiche Assoziation - es (defaultPeriod) wird seine Assoziation verlieren.
Ist es wahr? Wer hat noch das gleiche Problem?
Danke für die Antworten.
Antworten:
13 für die Antwort № 1Vermutlich, dein Team
Argument kommt von einer anderen Transaktion und einem anderen Hibernate Session
.
Wenn ein @Transactional
Methode gibt zurück, die TransactionManager
schließt die Session
was macht einige Aufräumarbeiten und Unsets (setzt auf null
) das Session
Feld von allen PersistentCollection
Instanzen. Ihre defaultPeriod
hat eine von diesen in seiner issues
Feld.
Hibernate "s Hibernate.initialize()
Erzwingt die Initialisierung eines Lazy PersistentCollection
, aber hat den folgenden Code (Anrufe AbstractPersistentCollection#forceInitialization()
)
if ( session == null ) {
throw new HibernateException( "collection is not associated with any session" );
}
Wenn Sie planen, die issues
Sammlung außerhalb des Originals @Transactional
Methode (der Code, der produziert Team
), müssen Sie die zugrunde liegenden Objekte laden. Entweder ändern Sie es in EAGER laden oder tun Sie, was Sie tun Hibernate.initialize()
.
Eine andere Lösung ist die Session
dauern länger als nur die Länge des ersten @Transactional
, aber ich habe keine Details dafür. Eine schnelle Google oder SO Suche sollte einige Optionen aufzeigen.
Das ist was passiert
Period defaultPeriod = team.getDefaultPeriod();
bekommt ein Period
Objekt mit ID (zB) 42
. Weil es in einem anderen passiert ist Session
das ist seitdem geschlossen worden, der issues
ist ein PersistentCollection
was hat a null
Session
Referenz und wird die werfen Exception
du erhältst.
Das machst du
List<Period> periods = _periodDAO.getPeriods(team);
Lassen Sie uns das sagen List
enthält ein Period
Objekt mit ID 42
so if
im
if (!periods.contains(defaultPeriod)) {
defaultPeriod = periods.get(periods.size() - 1);
}
wird nicht ausgeführt. Obwohl die equals()
kehrt zurück true
(contains()
kommt auch zurück true
und wird false
durch !
), die Objekte sind nicht gleich. Das in der List
hat einen Anhang (nicht null) Session
, damit man initialisiert werden kann. Aber deine, die, die du hältst defaultPeriod
kann nicht.