Hibernate Problem mit Lazy Loading bei @OneToMany Collections

H

HQLNeuling

Gast
Hallo zusammen,

ich bin absoluter Neuling in Hibernate und habe ein Problem beim Laden von Objekten aus der Datenbank. Ich habe als Beispiel in meiner Klasse Service eine Collection vom Typ ServExport und in meiner Klasse ServExport ein Objekt vom Typ Service:

Klasse Service
Java:
@OneToMany(mappedBy = "service")
private Collection<ServExport> exports = new HashSet<ServExport>();

Klasse ServImport
Java:
@ManyToOne
@JoinColumn
private Service service;

Lege ich nun Service-Objekte in die Datenbank ab und versuche sie an späterer Stelle wieder auszulesen und auf die Collections zuzugreifen, kommt die Fehlermeldung:

Java:
[2012-09-03 13:43:27,143] ERROR [main] org.slf4j.impl.JCLLoggerAdapter: failed to lazily initialize a collection of role: com.test.serviceAnwendung.db.hibernate.mapping.Service.exports, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.serviceAnwendung.db.hibernate.mapping.Service.exports, no session or session was closed
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
	at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
	at com.test.serviceAnwendung.db.hibernate.utils.HibernateTransactionHandler.getExports(HibernateTransactionHandler.java:509)
	at com.test.serviceAnwendung.TestAnwendung.getExports(TestAnwendung.java:114)
	at test.test.TestZugriff.main(TestZugriff.java:51)
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.serviceAnwendung.db.hibernate.mapping.Service.exports, no session or session was closed
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
	at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
	at com.test.serviceAnwendung.db.hibernate.utils.HibernateTransactionHandler.getExports(HibernateTransactionHandler.java:509)
	at com.test.serviceAnwendung.TestAnwendung.getExports(TestAnwendung.java:114)
	at test.test.TestZugriff.main(TestZugriff.java:51)

Ich habe mich im Internet ein bisschen zum Lazy Loading schlau gemacht und weiß das an dieser Stelle die Inhalte der Collection noch nachträglich aus der DB gelesen werden sollen. Verstehe nicht warum das nicht funktioniert, da ich eine Session geöffnet habe. Hatte auch schonmal versucht das Lazy Loading auszuschalten (
Code:
fetch = FetchType.EAGER
), aber das hat bei mehreren Collections in einer Klasse nicht funktioniert und will ich eigentlich auch nicht wegen der Performance.

Würde mich freuen wenn mir vllt jemand einen Tipp geben könnte! :)
 

Nogothrim

Aktives Mitglied
Ist es denn die selbe Session, mit der die Entity ursprünglich geladen wurde? Sonst ist natürlich der PersistenceContext futsch und es fliegt die LazyInitializationException. Ich kann mich auch dunkel erinnern, dass sich Sets bei dem Thema anders verhalten als Listen, ob das was damit zu tun hat, ka.
 
H

HQLNeuling

Gast
Hallo Danke erstmal für die Antwort! :)

Nein, es ist nicht die gleiche Session, denn wenn ich bei meiner Transaction die Methode commit() aufrufe, wird diese automatisch geschlossen!
Muss ich die Transaction die gesamte Zeit offen lassen solange bis ich die Collection benötige??
Weil ich lade mir ein Service Objekt aus der DB und möchte dann irgendwann (!) mal mit ner getterMethode auf die Collection zugreifen:

Java:
Service service = getService(serviceBezeichnung);
Collection<ServExport> exporte = service.getExports();
for(ServExport exp : export){ // An dieser Stelle wird die Exception geworfen
	// [...]
}

In der Methode getService(String serviceBezeichnung) lade ich das Objekt vorher:

Java:
private Service getService(String serviceBezeichnung){
	Service service = null;
        openSession();
	Transaction tx = session.beginTransaction();
	Query query = session.createQuery("select s from Service as s where s.bezeichnung = :bez");
	query.setParameter("bez", serviceBezeichnung);
	List<Service> services = query.list();
        if(services!=null){
               if(services.size()==1){
                    service = services.get(0);
               }
        }
	tx.commit(); // Hier wird die Session geschlossen
	return service;
}

Hier noch die Methode openSession():

Java:
private Session session;

public Session openSession() {
	if(session==null){
		session = HibernateSessionFactory.getInstance().getCurrentSession();
	}else if(session.isOpen()==false){
		session = HibernateSessionFactory.getInstance().getCurrentSession();
	}
	return session;
}

Das ist nicht die einzige 1:n Beziehung die ich so verdrahtet habe, die jeweiligen Objekte gebe ich an verschiedenen Stellen bis hoch zum Frontend bevor ich sie auslese! Jedes mal kommt dann die Exception...
 
H

HQLNeuling

Gast
Hier noch meine Hibernate Einstellungen, vllt hilft es ja:

[XML]
<hibernate-configuration>
<session-factory>

<!-- Datenbank Connection Einstellungen -->
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="connection.url">url</property>
<property name="connection.username">user</property>
<property name="connection.password">pw</property>

<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

<!-- Zusaetsliche Hibernate-Einstellungen -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>

<property name="c3p0.acquire_increment">3</property>
<property name="c3p0.idle_test_period">300</property>
<property name="c3p0.max_size">15</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">3</property>
<property name="c3p0.timeout">8000</property>

<!-- Auflistung der gemappten Klassen -->
<mapping class="com.test.serviceAnwendung.db.hibernate.mapping.Service"></mapping>
<mapping class="com.test.serviceAnwendung.db.hibernate.mapping.ServExport"></mapping>
<!-- [...] Andere gemappte Klassen [...] -->

</session-factory>
</hibernate-configuration>
[/XML]
 
N

nillehammer

Gast
Persistente Entities durchlaufen verschiedene Zustände. Nachdem eine Entity geladen und die zugehörige Session geschlossen wurde, ist sie im Detached Zustand. In diesem Zustand ist es nicht möglich, lazy geladene Members abzufragen. Ein entsprechender Versuch wird mit der von Dir beobachten Exception quitiert. Du musst also dafür sorgen, dass die Entity attached ist, wenn Du auf lazy loaded Members (wie Collections) zugreifen willst. Dafür gibt es verschiedene Ansätze:
-Du hälst die Session länger offen. Ist nur eingeschränkt zu empfehlen. Eine Session ist als kurzlebiges Wegschmeiß-Objekt gedacht. Bei zu ausgiebiger Nutzung langlebiger Sessions skaliert Deine Anwendung auch nicht mehr sehr gut.
-Du öffnest eine neue Session und (re-)attachest die Entity in die neue Session bevor Du auf Members zugreifst. Das geht entweder, indem Du mit der ID der Entity diese einfach neu lädst oder indem Du ein merge aufrufst.
 
H

HQLNeuling

Gast
-Du öffnest eine neue Session und (re-)attachest die Entity in die neue Session bevor Du auf Members zugreifst. Das geht entweder, indem Du mit der ID der Entity diese einfach neu lädst oder indem Du ein merge aufrufst.

Danke für den Tipp, ich rufe nun session.update(service) auf bevor ich auf die Elemente von session.getExports() zugreife! Das verhindert die Exception und löst das Problem. :) Jetzt muss ich nur noch schauen wie ich das schlau in meinen Code an die richtigen Stellen einbaue.

Vielen Dank! :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Lazy loading Problem Data Tier 2
boxi Hibernate Lazy Loading Problem Data Tier 2
C JPA FetchType.LAZY, Relation @OneToMany und Problem mit dem update Data Tier 1
N Problem beim initialisieren des Caches Data Tier 0
S JPA Problem mit Cascading Data Tier 1
M Eclipse 4 RCP Hibernate Problem Data Tier 3
K Problem mit EJBs und Transaktionen Data Tier 0
G JPA: Entity Klasse @JoinColumns Problem Data Tier 2
M JPA Problem: java.sql.SQLSyntaxErrorException: Data Tier 7
M MySql und JPA-Timestamp Problem Data Tier 8
J Hibernate Problem bei Master-Detail-Tabellen Data Tier 5
A JPA - ManyToMany Problem - keine Unique Mehrfachzuweisungen Data Tier 4
M Problem beim Laden von Objekten, die von anderen Applikationen in eine DB eingefügt wurden Data Tier 5
M Problem mit @Temporal Mapping und SQL Server Data Tier 3
P JPA - HashMap mit Many-to-Many Relation Problem Data Tier 4
B Problem mit @ManyToMany und CascadeType.ALL Data Tier 3
Blackskyliner [JPA][Anfänger] Problem mit Wertzuweisung aus Verbundtabelle Data Tier 2
B Problem mit org.hibernate.LazyInitializationException Data Tier 11
B DatenquellenUpdater extends Thread - Problem mit PermGenSpace Data Tier 5
S Problem beim Insert mit Hibernate Data Tier 9
Y [openJPA] Problem mit Transaktion? Data Tier 2
A @SecondaryTable Problem Data Tier 9
N Problem beim session.flush(); Data Tier 17
Y Postgres und JPA - Primärschlüssel Problem Data Tier 3
P SQL PRoblem Hibernate? Data Tier 8
Y EJB Problem mit Transaktionen Data Tier 7
M Transaction / Session Problem Data Tier 4
G JPA 2.0 Query Problem Data Tier 3
P CORBA Problem bei EJB 3.0 Anwendung in Glassfish v3 Data Tier 7
F Problem mit Hibernate Schema Update Data Tier 2
M Insert-Problem mit JPA/Hibernate Data Tier 4
megachucky JPA - Problem mit Persistence Unit / Context Data Tier 1
H Hibernate Problem Data Tier 4
D Performance Problem mit Prepared Statement Data Tier 6
T Problem mit openJPA Data Tier 7
P Problem mit Data Tier 9
GilbertGrape Cascade Problem (Hibernate) Data Tier 3
C JPA Problem mit attributeOverride und mehrspaltigem PK Data Tier 2
B select "neu" statement Problem (jpql) Data Tier 8
M Problem mit Hibernate und SLF4J - NoSuchMethodException Data Tier 3
G Connection Problem - WAS 6.1, Hibernate, OS Authentication Data Tier 1
K Hibernate update-Problem Data Tier 36
J hibernate problem Data Tier 14
N Hibernate - Problem mit Update/Insert Data Tier 4
B Problem mit @PersistenceContext Data Tier 4
G Problem with mapped of the tables at one to one relationship Data Tier 8
O Hibernate Fragen zu Lazy Loading Data Tier 5
D JPA Entities mit Proxies ausserhalb einer Session (Lazy Loading) Data Tier 0
M JSF Lazy Listen nachladen? Data Tier 2
Y Nachladen von Lazy Objekten Data Tier 4
D Lazy Loading bei Aggregaten (DDD) Data Tier 6
V JPA/Hibernate Lazy Collections ignorieren. Data Tier 1
K Collections Eager Loading Data Tier 5

Ähnliche Java Themen

Neue Themen


Oben