Wie kann man das org.hibernate.LazyInitializationException - konnte nicht initialisiert werden proxy - keine Sitzung
Bekomme ich die folgende exception:
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at sei.persistence.wf.entities.Element_$$_jvstc68_47.getNote(Element_$$_jvstc68_47.java)
at JSON_to_XML.createBpmnRepresantation(JSON_to_XML.java:139)
at JSON_to_XML.main(JSON_to_XML.java:84)
wenn ich versuche, rufen Sie aus der main die folgenden Zeilen:
Model subProcessModel = getModelByModelGroup(1112);
System.out.println(subProcessModel.getElement().getNote());
Implementiert habe ich die getModelByModelGroup(int modelgroupid)
Methode zunächst so :
public static Model getModelByModelGroup(int modelGroupId, boolean openTransaction) {
Session session = SessionFactoryHelper.getSessionFactory().getCurrentSession();
Transaction tx = null;
if (openTransaction) {
tx = session.getTransaction();
}
String responseMessage = "";
try {
if (openTransaction) {
tx.begin();
}
Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
query.setParameter("modelGroupId", modelGroupId);
List<Model> modelList = (List<Model>)query.list();
Model model = null;
for (Model m : modelList) {
if (m.getModelType().getId() == 3) {
model = m;
break;
}
}
if (model == null) {
Object[] arrModels = modelList.toArray();
if (arrModels.length == 0) {
throw new Exception("Non esiste ");
}
model = (Model)arrModels[0];
}
if (openTransaction) {
tx.commit();
}
return model;
} catch(Exception ex) {
if (openTransaction) {
tx.rollback();
}
ex.printStackTrace();
if (responseMessage.compareTo("") == 0) {
responseMessage = "Error" + ex.getMessage();
}
return null;
}
}
und bekam die Ausnahme. Dann ein Freund schlug mir vor, zu testen immer die session und Holen Sie sich die aktuellen session um diesen Fehler zu vermeiden. Also ich habe das:
public static Model getModelByModelGroup(int modelGroupId) {
Session session = null;
boolean openSession = session == null;
Transaction tx = null;
if (openSession) {
session = SessionFactoryHelper.getSessionFactory().getCurrentSession();
tx = session.getTransaction();
}
String responseMessage = "";
try {
if (openSession) {
tx.begin();
}
Query query = session.createQuery("from Model where modelGroup.id = :modelGroupId");
query.setParameter("modelGroupId", modelGroupId);
List<Model> modelList = (List<Model>)query.list();
Model model = null;
for (Model m : modelList) {
if (m.getModelType().getId() == 3) {
model = m;
break;
}
}
if (model == null) {
Object[] arrModels = modelList.toArray();
if (arrModels.length == 0) {
throw new RuntimeException("Non esiste");
}
model = (Model)arrModels[0];
if (openSession) {
tx.commit();
}
return model;
} catch(RuntimeException ex) {
if (openSession) {
tx.rollback();
}
ex.printStackTrace();
if (responseMessage.compareTo("") == 0) {
responseMessage = "Error" + ex.getMessage();
}
return null;
}
}
}
aber immer noch die gleichen Fehler.
Ich lese eine Menge für diese Fehler gefunden und einige mögliche Lösungen. Einer von Ihnen war, war lazyLoad für falsch, aber ich bin nicht erlaubt, dies zu tun, das ist, warum ich vorgeschlagen wurde, um die session
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier was falsch läuft ist, dass Ihre session-management-Konfiguration wird auf Sitzung schließen, wenn Sie ein commit für die Transaktion. Prüfen Sie, ob Sie so etwas wie:
in Ihrer Konfiguration.
Um dieses problem zu überwinden, könnten Sie die änderung der Konfiguration der session-factory oder öffnen einer anderen Sitzung, und nur als Frage für diejenigen, die faul geladenen Objekte. Aber was würde ich vorschlagen, hier ist die Initialisierung dieses lazy-Kollektion in getModelByModelGroup selbst und rufen:
ist, wenn Sie noch in der aktiven Sitzung.
Und eine Letzte Sache. Eine freundliche Beratung. Sie haben so etwas in Ihrer Methode:
Bitte statt dieser code filtern nur jene Modelle mit der Typ-id gleich 3 ist in der query-Anweisung nur ein paar Zeilen weiter oben.
Einige mehr Lesen:
Sitzung der werkseitigen Konfiguration
problem mit geschlossenen Sitzung
Wenn du mit Spring markieren Sie die Klasse als @Transactional, dann wird der Frühling Griff-session-management.
Mithilfe
@Transactional
viele wichtige Aspekte, wie die transaction propagation-automatisch behandelt werden. In diesem Fall, wenn ein anderes Transaktions-Methode ist die Methode aufgerufen wird, haben die Möglichkeit, sich den Laufenden Transaktion die Vermeidung der "keine session" Ausnahme.@EnableTransactionManagement
zu Ihrer Konfiguration, um zu ermöglichen, Transaktionen. "wenn ein anderes Transaktions-Methode ist die Methode aufgerufen wird, haben die Möglichkeit, sich den Laufenden Transaktion" dieses Verhalten ist unterschiedlich für die verschiedenen Arten von Transaktionen implementiert werden, d.h. die Schnittstelle proxy vs-Klasse proxy oder AspectJ weaving. Siehe die Dokumentation.Transactional
annotation ist also empfehlenswert, nicht nur für ändern Transaktionen, sondern auch für den Zugriff auf nur diejenigen ?Können Sie versuchen,
in hibernate.cfg.xml oder persistence.xml
Das problem im Auge zu behalten, mit dieser Eigenschaft sind gut erklärt hier
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
hibernate.enable_lazy_load_no_trans
ist ein Anti-Muster, richtig?Der beste Weg, um behandeln Sie die
LazyInitializationException
ist die Verwendung derJOIN FETCH
Richtlinie:Sowieso, verwenden Sie NICHT die folgenden Anti-Patterns wie von einigen vorgeschlagen, der die Antworten:
hibernate.enable_lazy_load_no_trans
Manchmal ein DTO Projektion ist eine bessere Wahl als das abrufen von Entitäten, und auf diese Weise, Sie erhalten keine
LazyInitializationException
.FetchType=EAGER
, aber das ist nicht die richtige Lösung, richtig ?@Transactional
service.War ich immer die gleichen Fehler für ein eins-zu-viele-Beziehungen für folgende annotation.
Geändert, wie unten nach Zugabe von fetch=FetchType.BEGIERIG, es funktionierte für mich.
Diese Ausnahme, weil, wenn Sie anrufen
session.getEntityById()
, wird die Sitzung geschlossen. So müssen Sie re-befestigen Sie die Einheit an der Sitzung. Oder die Einfache Lösung ist einfach zu konfigurierendefault-lazy="false"
zu Ihrementity.hbm.xml
oder wenn Sie Anmerkungen fügen Sie einfach@Proxy(lazy=false)
zu Ihrer entity-Klasse.wenn Sie spring data jpa , spring boot-Sie können fügen Sie diese Zeile in der Anwendung.Eigenschaften
Ich hatte das gleiche Problem. Ich denke, eine andere Möglichkeit dieses Problem zu beheben ist, dass können Sie ändern Sie die Abfrage, um join-fetch-Element aus dem Modell wie folgt:
Gibt es mehrere gute Antworten hier, die mit diesem Fehler in einem breiten Anwendungsbereich. Ich lief in einer spezifischen situation mit Spring Security, die eine schnelle, wenn auch wahrscheinlich nicht optimal, fix.
Während die Berechtigung des Anwenders (sofort nach der Anmeldung und Authentifizierung) ich war die Prüfung einer Benutzer-Entität für eine bestimmte Behörde in einer benutzerdefinierten Klasse, die Sie erweitert SimpleUrlAuthenticationSuccessHandler.
Meine Benutzer-Entität implementiert UserDetails und hat eine Reihe von lazy geladen Rollen, die warf die "org.hibernate.LazyInitializationException - konnte nicht initialisiert werden proxy - keine Session" Ausnahme. Ändern Set von "fetch=FetchType.FAUL" zu "fetch=FetchType.BEGIERIG" Feste das für mich.
Wenn Sie mit JPQL, JOIN FETCH ist der einfachste Weg:
http://www.objectdb.com/java/jpa/query/jpql/from#LEFT_OUTER_INNER_JOIN_FETCH_
Dies bedeutet, dass das Objekt, das Sie zugreifen möchten, ist nicht geladen, so eine Abfrage schreiben, das macht einen join fetch von dem Objekt, das Sie zugreifen möchten.
ZB:
Wenn Sie versuchen, um ObjectB von ObjectA, wo ObjectB ist ein Fremdschlüssel in der ObjectA.
Abfrage :
Wenn Sie
Grail's
Rahmen, es ist einfach zu beheben lazy-Initialisierung Ausnahme mithilfeLazy
keyword auf bestimmtes Feld in der Domain-Klasse.For-Beispiel:
Weitere Informationen finden hier
Bedeutet dies, dass Sie mithilfe von JPA oder hibernate in Ihrem code und der Durchführung geändert wird, der Betrieb DB, ohne die business-Logik der Transaktion.
Also einfache Lösung für dieses, ist mark-Stück von code @Transactional
Dank.
In meinem Fall eine unangebrachte
session.clear()
war dieses problem verursacht.Konfrontiert die gleiche Ausnahme in unterschiedlichen Anwendungsfall.
Anwendungsfall : Versuchen das Lesen von Daten aus DB mit DTO Projektion.
Lösung: Verwenden bekommen Methode statt laden.
Generische Operation
}
Persistenz-Klasse
CustomerDAO Schnittstelle
Entity-Transfer-Objekt Der Klasse
}
Factory-Klasse
}
Entität spezifische DAO
}
Abrufen von Daten: Test-Klasse
Vorliegenden Daten
Abfrage und Ausgabe generiert durch Hibernate System
Ruhezustand: wählen Sie customer0_.Id als Id1_0_0_, customer0_.Stadt als City2_0_0_, customer0_.Namen wie Name3_0_0_ von CustomerLab31 customer0_ wo customer0_.Id=?
CustomerName -> Cody , "Kundenadresse" - > LA
verwendet session.bekommen(*.Klasse, id); aber nicht laden-Funktion
könnten Sie auch gelöst durch hinzufügen von lazy=false in in Ihr *.hbm.xml Datei, oder Sie können init Ihr Objekt in Hibernate.init(Object), wenn Sie Objekt von db
Tun, die folgenden änderungen in servlet-context.xml