# Hibernate in non-EE Server/Client-App (Topic geändert)



## sparrow (3. Sep 2007)

Hallo liebes Forum,

Hibernate gefällt mir im Augenblick sehr gut, vor allem dieses "LazyLoading" hat es mir angetan.

Ich habe das aus einem Buch entnommene Beispiel von einer Pizzerienverwaltung nach und nach so umgebaut, dass das ganze Verteilt als RMI-Applikation läuft.
Auf dem Server läuft also die Logik der Datenstruktur und stellt Schnittstellen (Controller) zur Verfügung, auf dem Client läuft nur die GUI die Anfragen an den Controller schickt.
Rein Programmtechnisch ist das ganze herrlich, da schieße ich nur Objekte zwischen Server und Client hin und her, die Controller sind halt über RMI vom Client aus ansprechbar.

So kann ich mir problemlos zum Beispiel eine Objekt der Klasse Pizza vom Server beschaffen. Die Klasse Pizza gibt es sowohl auf dem Server als auch auf dem Client, ich frage den Server nach einem Pizza Objekt und der sendet sie mir zu (RMI Methodenaufruf).

Nun hat aber auch jede Pizza Belag, jeder Belag wird durch die Klasse "Topping" repräsentiert.
Pizza und Topping stehen in einer 1:N-Beziehung, im Programm mit Hibernate daduch gelöst, dass Pizza eine Funktion _List<Topping> getToppings()_ besitzt.
Das funktioniert bei einer normalen, lokalen Anwendung problemlos.... und macht richtig Spaß.
Rufe ich ein Objekt "Pizza" ab, dann kann ich auf alle Felder zugreifen, greife ich per getToppings auf die Beläge zu schmeißt im Hintergrund Hibernate schnell eine Anfrage an und holt mir die Toppings zur Pizza. Die Daten werden also wirklich nur dann geholt wenn sie gebraucht werden. Das spart Resourcen und Zeit.

Das funktioniert aber logischerweise nicht wenn ich das Pizza-Objekt per RMI zum Client übertragen habe.
Dort gibt es keine Hibernate-Instanz und dementsprechend keine Hibernate-Session die aber offensichtlich gebraucht wird um eine LazyLoading-Verknüpfung aufzulösen.
Hat jemand eine Ahnung wie es trotzdem funktioniert? Diese "Laden bei Bedarf"-Geschichte gefällt mir nämlich sehr gut.

Natürlich gibt es auch die Möglichkeit dafür zu sorgen, dass die Verknüpfung der Objekte statisch geschieht. Dann würde Hibernate immer wenn ein Pizza-Objekt geladen wird auch die Toppings mitladen. Dann funktioniert auch das übertragen per RMI problemlos.... aber irgendwie fühlt sich das an als würde das wichtigste Feature von Hibernate nicht genutzt werden 

Vielleicht kennt ja jemand das Problem und hilft mir weiter.


Ich danke!


Gruß Sparrow


----------



## SlaterB (3. Sep 2007)

da gibts nichts groß zu sagen, das ist auch kein Informatik-Problem (persönliche Meinung  ),

wenn du im Supermarkt einkaufst und dann zuhause feststellst, dass noch Milch fehlt,
dann gibt es nur zwei grundsätzliche Strategien:
a) bei fehlenden Sachen nochmal einkaufen fahren (zweite RMI-Anfrage, im Grunde ja das, was Hibernate mit der DB macht, nein, Hibernate unterstützt nicht RMI  )
b) vorher genauen Einkaufszettel schreiben (bei der ersten Anfrage alles laden oder genau angeben, was mitzuladen ist)


----------



## sparrow (3. Sep 2007)

Eine 2. RMI Anfrage wäre an sich nicht das Problem.
Ich will aber, dass das automatisch geht.
Hibernate verwendet dafür Proxy-Klassen, also müssten die irgendwie per RMI kommunizieren können.
Sprich: Ob ich lokal arbeite oder verteilt via RMI, eine Anfrage auf die Verknüpfung soll die benötigten Objekte nachladen.


----------



## SlaterB (3. Sep 2007)

ich sollte selber auch öfter Google anschmeißen bevor ich 'nein, Hibernate unterstützt nicht RMI' schreibe 

'Remote Lazy Loading' scheint ein Stichwort zu sein, schau da mal rein:
http://www.hibernate.org/377.html
http://h3t.sourceforge.net/
bzw. suche nach diesem Stichwort


----------



## sparrow (3. Sep 2007)

Moah, danke SlaterB!
Genau sowas hab ich gesucht, aber irgenwie war ich mit den Proxy-Klassen die ganze Zeit auf dem falschen Weg.
Ich habe ständig danach gesucht wie ich da etwas umbiegen muss, dass bereits eine Lösung besteht... nunja.... 

Ich danke vielmals!


----------



## sparrow (6. Sep 2007)

Ich führe diesen Thread einfach mal unter Änderung des Topics weiter.

Die beiden Links die gepostet wurden zeigen beide auf Möglichkeiten die ein Programm benötigen das auf J2EE-Basis funktioniert. Das ist mir aber eigentlich etwas zu "dick". Schon der Rattenschwanz der an Hibernate an Bibliotheken dran hängt ist eine Menge.

Gibt es denn tatsächlich keine Möglichkeit Hibernate in einer normalen Client/Server-Applikation zu verwenden wobei der Client nicht direkt auf die Datenbank zugreift?
Alle Verknüpfung beim Ausliefern eines Objekts mit auszugeben scheidet definitiv aus.


Gruß
Sparrow


----------



## ms (6. Sep 2007)

Was für eine Client-Server-Lösung schwebt dir denn vor, wenn dir ein Applikationserver ' zu dick' ist?

ms


----------



## sparrow (6. Sep 2007)

Im Augenblick möchte ich einen mobilen Mailclient in eine Mini-Groupware verwandeln.


----------



## ms (6. Sep 2007)

Ok, und wie soll die Transportschicht aussehen?
EJB's möchtest du ja nicht.

ms


----------



## sparrow (6. Sep 2007)

Am liebsten würde ich mit RMI arbeiten.
Das würde die Umsetzung sehr vereinfachen bei dem Umstricken der Software. Ich würde dann einfach den Teil der Applikation die für den Serverbetrieb nötig sind aus dem Programm heraus nehmen und auf dem Server laufen lassen. Der Server würde also entsprechende Schnittstellen für RMI zur Verfügung stellen.


----------



## sparrow (8. Sep 2007)

Hallo liebes Forum,

Ich habe mich weiter mit diesem Problem beschäftigt und eine mögliche Lösung gefunden. Es funktioniert ziemlich gut, ih möchte euch nun fragen was ihr davon haltet.

Das Problem ist ja, dass ich das von Hibernate erstellte Objekt nicht einfach zum Client schicken kann, also wäre es sinnvoll das Objekt gar nicht zu verschicken.
Dazu kam die Frage von ms nach der Transportschicht... das hat mich auf eine Idee gebracht.


Ich bin jetzt so vorgegangen, dass es für jeden "Vorfall" folgende Konstellation gibt:

Client
GUI - Klasse
GUIRemote - Klasse

Server
Controller - Klasse
ControllerRemote - Klasse


Die Handhabung der persistenten Objekte... eigentlich alles läuft auf dem Server.
Zum Kommunikation mit dem Server greift der Client via RMI auf den ServerController für den Vorfall zu und instanziert dafür ControllerRemote. Über diese Schnittstelle lässt der Client dem Server Informationen zukommen.
Änderungen an der GUI nimmt allerdings auch der ServerController vor.
Dafür hält die GUI ebenfalls ein Interface bereit welches über RMI kommuniziert und vom Server angesprochen wird.


Ein Vorgang der Registrierung würde wie folgt aussehen:

Server
Init: stellt die RMI-Registry zur Verfügung
Binden des ServerControllers an die Registry

Client
Objekt Init: Client beschafft sich das RemoteObjekt des Servers
Meldet sein eigenes Remote Objekt am Server an


Anschließend leitet der Client seine Anfragen an den Server die der Server direkt über das Remote-Objekt des Clients ausführt.
Wird der Client beendet sorgt diese für ein unbind seines Remote-Objekts.



Sinnvoll oder nicht?


Gruß
Sparrow


----------

