# Hibernate - Best Practice für Lazy Loading



## inv_zim (25. Okt 2011)

Hallo,

ich habe (mal wieder) bei Hibernate einen Punkt, an dem ich nicht weiter komme, bzw. ich bin mir nicht sicher ob meine Lösung in Ordnung ist.

*Kurze Vorgeschichte:*
Ich habe eine Client Server Anwendung, die eine Videoüberwachung möglich macht. Daten über Kameras, erfolgte Alarme, etc. liegen in einer *Datenbank *die ich mit Hibernate anspreche.
Die Kamera-Daten werden vom Client angefragt, der Server stellt eine HTTP Anfrage an die Kameras, die wiederum aus der DB gelesen werden und sendet diese zurück zu den Clients.
Der Server selbst fragt außerdem durchgehend bei den Kameras die Status ab. Damit habe ich *mehrere Threads*, die Hibernate benutzen. Sämtliche Collections der Kameras werden lazy gefetcht, unter anderem auch die Softwareversion der Kamera, welche wiederum eine Collection mit API-Befehlen enthält.


```
+Camera
|
+--+Software
    |
    +ApiCommands
```

*Das Problem:*
Wir haben DataAccessObjects angelegt um die Zugriffe auf die Objekte zu vereinheitlichen. Dabei habe ich mich an das Beispiel dieser Seite gehalten. 
Ich habe nun eine Klasse, die die Kamerastatus abfragt, und dabei wie folgend vorgeht:

Über SessionFactory#getCurrentSession() die Session für den Thread holen
Dem CameraDao diese Session bekannt machen
Eine neue Transaction für diese Session beginnen
Das CameraDao eine Liste aller Kameras holen lassen
Die Transaction commiten

Diese Collection möchte ich nun durchgehen, und für jede Kamera den API-Befehl ermitteln, an den ich eine Anfrage senden muss um den Status zu erfahren. Das schlägt jedoch später fehl, da die Session schon geschlossen ist. Meine Ansätze waren:

A. Den Fetch für den Lazy load in einer neuen Transaktion durchführen
Schlug fehl. ("no session or session was closed").

B. Während der ersten Transaktion die benötigten Objekte referenzieren, um den Lazy Load zu erzwingen und die Attribute später zu verwenden. Extra die ganze Collection durchgehen, um bei jedem einzelnen Zugriffe durchzuführen wirkt irgendwie komisch auf mich, kann ich vielleicht bei einem fetch sagen, er soll direkt einen Join für dieses Feld machen und mir das direkt mitliefern?

(C. Lazy Loading für das Kameraobjekt ausschalten ist keine Option).

Das ist jetzt einiges an Text, und ich bin mir nicht sicher, ob ich mittendrin den Faden verloren habe. Hier jetzt von allem Code zu posten würde den Rahmen sprengen, wenn ihr aber einen Blick auf einzelne Abschnitte werfen wollt, kann ich diese hier reinstellen. Die Grundfrage soll sich auch gar nicht direkt auf mein Programm beziehen, sondern eher darum, wie man so etwas generell lösen kann?

Gruß und danke,

Tim


----------



## maki (25. Okt 2011)

Hol dir doch die Daten gleich  mit einem Fetch Join wenn du weisst dass du sie brauchen wirst, genau dafür ist er ja da.

Nachtrag: Das GenericDao ist ja nur ein Grundgerüst, in den konkreten Daos darfst und solltest du ja spezifische Dinge implementieren.


----------



## nillehammer (25. Okt 2011)

In Webanwendungen gibt es zwei Patterns, um genau das zu machen, was Du willst und trotzdem nicht auf Lazy Loading zu verzichten.
- Open Session in View Pattern + Joinen des detached (Kamera)-Objects mit der Session
- Lang laufende Sessions
Ich würde Dir das erste empfehlen, weil es hier nur um die Anzeige geht. Das zweite wird eher für Wizard-artige Dialoge benutzt, wo man über mehrere Seiten Daten eingibt. Nimm die Begriffe mal für google. Falls noch was unklar ist, meld Dich nochmal.


----------



## inv_zim (25. Okt 2011)

maki hat gesagt.:


> Nachtrag: Das GenericDao ist ja nur ein Grundgerüst, in den konkreten Daos darfst und solltest du ja spezifische Dinge implementieren.



Das ist klar, spezifische Dinge sind auch enthalten 

Danke für den Ansatz mit dem Fetch-Join, natürlich funktioniert das. Wald, Bäume...


----------

