org.hibernate.LazyInitializationException: konnte nicht initialisiert proxy - besitzenden-Sitzung wurde geschlossen
Ich erhalte immer die Fehlermeldung "Exception in thread "main" org.hibernate.LazyInitializationException: konnte nicht initialisiert proxy - besitzenden-Sitzung wurde geschlossen", wenn ich den folgenden code ausführen:
public ArrayList<ProfileDTO> getInitialProfiles(Contracts ct){
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
ArrayList<ProfileDTO> profileDTOs=new ArrayList<ProfileDTO>();
try{
Hibernate.initialize(ct);
SQLQuery query=session.createSQLQuery("select {b.*},{p.*},{t.*} from bidtool.bt_boiler_plates b,bidtool.bt_profile p,bidtool.bt_trade_lane t where b.contract_id=:val AND p.contract_id=:val AND t.contract_id=:val")
.addEntity("b",Boiler_Plates.class)
.addEntity("p",BidToolProfiles.class)
.addEntity("t",BidToolTradeLanes.class);
query.setParameter("val", ct.getContract_id());
List list=query.list();
Iterator iteContract = list.iterator();
while ( iteContract.hasNext() ) {
Object[] pair =(Object[]) iteContract.next();
Boiler_Plates bp=(Boiler_Plates)pair[0];
BidToolProfiles p=(BidToolProfiles)pair[1];
ProfileDTO profileDTO=new ProfileDTO();
profileDTO.setProfileId(p.getProfileId());
profileDTO.setBt_contracts(p.getBt_contracts());
profileDTO.setCreated(p.getCreated());
profileDTO.setProfileContent(p.getProfileContent());
profileDTO.setEditable(p.getEditable());
profileDTO.setProfileName(p.getProfileName());
profileDTOs.add(profileDTO);
}
return profileDTOs;
}
catch(Exception ex){
System.out.println(ex.getMessage());
return profileDTOs;
}
finally{
session.flush();
session.close();
}
}
Funktioniert es einwandfrei, wenn ich die session nicht schließen, aber ich kann das nicht. Muss ich die Sitzung schließen. Ihre Hilfe wird geschätzt. Danke.
Antwort von Jeshurun dieses problem gelöst. Dank
InformationsquelleAutor Alok | 2012-05-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wird der Fehler ausgelöst, wenn Sie auf eine Vereinigung oder eine Auflistung in einer hibernate-Entität, nachdem die Sitzung geschlossen wurde. Suche bei deinem code, ich vermute, das problem liegt wahrscheinlich in der folgenden Zeile:
profileDTO.setBt_contracts(p.getBt_contracts());
wenn Sie versuchen, Zugriff auf diese Auflistung an anderer Stelle in Ihrem code aus einer anderen Session.
Versuchen Sie Ihre Abfrage zu:
select {b.*},{p.*},{t.*} from bidtool.bt_boiler_plates b,bidtool.bt_profile p,bidtool.bt_trade_lane t left join fetch p.bt_contracts btcontracts where b.contract_id=:val AND p.contract_id=:val AND t.contract_id=:val
Beachten Sie, dass ich habe ein join-fetch auf die Sammlung. Dies sollte sicherstellen, dass die Verträge, die Sammlung geholt wird, gleichzeitig die
BidToolProfiles
Person abgeholt werden. Auch versuchen, die Auflistung zu initialisieren, bevor Sie es in Ihrem DTO.InformationsquelleAutor Jeshurun
Gut, Sie brauchen zum initialisieren jedes Objekt, das Sie verwenden möchten, sobald die session geschlossen wird.
Angenommen, Sie haben eine User-Entität mit lazy OneToOne Assoziation mit seiner Adresse. Und angenommen, Sie laden den Benutzer während der Sitzung geöffnet ist. Da die Adresse wird lazy geladen, wenn Sie das erste mal rufe eine Methode auf die Adresse (
user.getAddress().getStreet()
zum Beispiel), Hibernate ausführen einer Abfrage zum laden der Adresse des Benutzers, und somit in der Lage sein, um Ihnen den Zugang zu Ihrer Straße. Aber wenn die Sitzung geschlossen ist, gibt es keine Verbindung zu der Datenbank nicht mehr, die User-Entität getrennt, und Überwintern somit wirft diese exception.Verwenden
Hibernate.initialize()
zum initialisieren der Objekte, die Sie benötigen, oder eine Abfrage ausführen, die die notwendigen holt sich alles zu laden benötigt auf einmal.Randnotiz: dein exception-handling ist schrecklich. Wenn Sie gefragt, um die Rückkehr der profile, anstatt zu sagen: "sorry, aber ich konnte nicht, wegen der folgenden Ausnahme", dass Sie im Grunde ignorieren die Ausnahme und sagen: "Es gibt kein Profil in der Datenbank". Bitte stellen Sie sich ein Krebs-detection-system funktioniert auf diese Weise. Möchten Sie, dass Ihr Krebs unentdeckt bleiben, weil das system hatte eine Ausnahme?
InformationsquelleAutor JB Nizet
Wie sind Sie mit dieser Methode? Was sind Ihre Zuordnungen wie? Welche Eigenschaften haben Sie lazy loading aktiviert? Dies ist eine web-app? Erstellen Sie eine ProfileDTO aber was getBt_contracts. Das wird Rückkehr Zeug aus der "Session-enabled" BidToolProfiles also, wenn Sie Zugang lazy-loaded Eigenschaften nach, die Methode gibt dann diese Fehlermeldung.
Dies ist nur ein Beispiel von dem, was ich denke, ist falsch, da kann ich sehen, Ihre Zuordnungen. Die wichtige Sache hier ist, dass sollte die Sitzung schließen, nachdem Sie faul geladen, dass ALLE Eigenschaften, die Sie benötigen zum ausführen der gewünschten Aufgabe.
Wieder - je nachdem, ob dies ist eine web-app oder nicht, können Sie gehen für verschiedene session-m management-Strategien (Session-per-Request auf web-apps, Session pro Thread, wenn Ihr eine desktop-app, etc)
InformationsquelleAutor Yannis
Verwenden
session.merge()
verschmelzen die Instanz geladen, aus einer alten Sitzung mit der neuen session. Dies bedeutet übrigens Hibernate lädt die entity wieder aus der Datenbank.Die andere Möglichkeit ist die Vermeidung von lazy loading - entweder in der Zuordnung oder durch den Zugriff auf die erforderlichen Werte, solange die session noch offen ist (auch wenn die Werte nicht notwendig, in diesem moment).
InformationsquelleAutor Johanna