2013-01-16 7 views
7

Korrigieren Sie mich, wenn dies ein genaues Duplikat ist, ich weiß, dass dieses Thema oft diskutiert wird, aber keine definitive Antwort finden kann.MVC mit faulen Laden

Die Frage:

Was ist die beste praktische Lösung Hibernate Objekte in einem MVC Webapp Handhabung?

Die Details:

Ich bin mit Hibernate und verzögertes Laden nutzen möchten, soweit möglich.
Ich arbeite in einer MVC-Stil Webapp.
Ich hasse es, lazy laden Initialisierung Ausnahmen.
Ich hasse es, Hibernate-Objekte zwischen Transaktionen neu zu verbinden.

Die Optionen:

  1. Eager Last alles
    • Löst das verzögerte Initialisierung Problem aber macht meine Anfragen größer
  2. Konzept einige 'Open Session in View' Verwenden
    • Ich liebe die Einfachheit davon
    • Objekte müssen noch wieder angebracht werden, und in einem AJAXy Setup, recht häufig
    • Eine Sitzung für jede Anforderung
  3. ‚touch‘ Artikel I vor dem Verlassen der Transaktion benötigen bei
    • Scheint fadenscheinigen geöffnet beste .. und langweilig
  4. verschiedenen erstellen, vereinfacht, 'losgelöst' Objekte so nie die Ansicht Echt Hibernate sieht Objekte
    • Th ese könnte einfacher als voll Hibernate Objekte zu sein, so ist es nicht eine volle eifrig Last des
    • Modell wie
    • ich dies in Orten empfohlen habe gehört, aber scheint wie mehr Haftung/code/Arbeit
  5. Öffnen Sie eine Sitzung wann immer ich mit Hibernate-Objekten interagieren möchte.
    • Dies kann in einer Spring Service-Schicht ziemlich schön verpackt werden, scheint aber manchmal übermäßig. Zum Beispiel: Ich möchte hibernateObject.getRelatedObjects() aber so etwas wie springService.getRelatedObjects(hibernateObject) sagen müssen

bin ich etwas fehlt?
Habe ich Dinge überdenken?
Habe ich Dinge unterbewertet?

PS:

Für einen Web-Framework ZK Ich verwende aber nicht wirklich will, eine ZK spezifische Antwort.
Ich benutze auch Frühling und bin cool mit einer Frühlingsspezifischen Antwort, wie es so allgegenwärtig ist.

Antwort

5

Verwenden Sie 4-ish - Verwenden Sie keine offene Sitzung in Ansicht, lassen Sie Ihre Hibernate-Entitäten nicht bis zur Ansicht sprudeln, sondern Transformatoren übersetzen zwischen den Hibernate-Entitäten und Ihren Domänenobjekten oder 'View-Beans' abhängig davon, wie Sie es arbeiten möchten.

Ich denke an Hibernate-Entitäten als nur eine Persistenzstrategie nicht ein Domänenmodell oder UI-Darstellung.

+0

Prost Bedwyr, ich glaube, ich diesen Ansatz werde. Es ist ein bisschen mehr Code, aber die Trennung von Ansicht und Modell sollte es wert sein. –

+0

Ich stimme dieser Antwort zu und stimme sie zu, ich möchte nur ein Stück Code hinzufügen, das Sie vielleicht nützlich finden. Hier ist ein Kopierer mit variabler Tiefe, er hängt von der Feder ab, ist aber leichter als eine komplette Kartierungslösung wie Dozer. https://gist.github.com/thinkbigthings/5488327 – Jay

+0

Auch hier ist ein Hibernate Unproxifier: https: // gist.github.com/thinkbigthings/5141813 – Jay

1

Das Mischen der Präsentationsschicht mit der Datenzugriffsebene ist ein Designproblem.

Ihre Ansicht sollte über einen Controller auf das Modell zugreifen, aber mithilfe von Hibernate-Objekten mischen Sie Ebenen. IMO Data Access sollte eine weitere Ebene unterhalb des Modells sein. Auch wenn Ihre Entitäten in einem XML-Code kommentiert oder definiert sind, sind sie vom eigentlichen Modell getrennt.

Stellen Sie eine Facade oder einen Manager vor, der die Hibernate-Logik kapselt und über einen Servicevertrag für die Controller verfügbar macht und sinnvolle Objekte zurückgibt, die diese Entitäten darstellen. Wenn überhaupt, würde ich für Option gehen 4.

+0

Dank Gamb. Es ist ein bisschen mehr Code und Arbeit, aber ich denke, es wird für eine sauberere, testbarere Anwendung sorgen. Wenn ich sowohl Ihre als auch @ Bedwyrs akzeptieren könnte, würde ich eine zufällig auswählen. –

+0

@SeanConnolly Keine Sorge, ich bin froh, Ihnen helfen zu können :) – Gamb

3

Es gibt drei Möglichkeiten:

Verwenden eifrig holen Last für Ihre Attribute: kann ein Problem sein, wenn Sie eine große Datentabelle haben.

Verwenden Sie einen Filter namens OpenSessionInView: dieser Filter wird die Sitzung geöffnet, bis die volle Last Ihrer Webseite halten. Wenn in diesem Ladevorgang ein Hibernate-Objekt angefordert wurde, wird die Sitzung geöffnet und die Ausnahme "Lazy Loading" wird vermieden.

Benutzer VOs (valueble Objekte): in Ihrer Anwendung werden zwei Arten von Objekten haben. Ein Objekt, das zwischen der Persistence- und Business-Schicht und einem Objekt für Ihre Ansichtsebene übergeben wird. Zum Beispiel UserVO und UserModel. Ein vo wird verwendet, um Informationen zwischen Ansichts- und Business-Schicht zu transportieren. In Ihrer Geschäftsimplementierung verwenden Sie das vo, um das Modellobjekt zu füllen, um es an Ihre Persistenzschicht zu senden. Wenn Sie dieses Muster verwenden, haben Sie keine Ausnahme für mehr Lazy Load, da alle benötigten Informationen in Ihr vo-Objekt eingefügt werden, wenn dies erforderlich ist.

Einige Referenzen:
OpenSessionInView
Eager Fetching Load
Hibernate Performance tips

Verwandte Themen