2009-06-05 8 views
1

Also habe ich eine einfache Webanwendung mit Spring MVC + Hibernate und verwende den OpenSessionInViewFilter. Ich habe kürzlich darüber nachgedacht, die Benutzeroberfläche durch etwas wie Flex oder GWT zu ersetzen.Wann wird Lazy Loading zu einem Problem in RIAs?

Zuerst dachte ich, es wäre einfach, weil ich einfach meine Service-Schicht vom neuen Frontend treffen kann. Aber wenn ich das ein bisschen mehr betrachte, bin ich etwas nervös in Bezug auf die Probleme beim Lazy Loading. Bei Verwendung eines herkömmlichen Web-Frontends ist das kein Problem, da ich die offene Sitzung im Blick habe ... alles, was für die Ansicht geladen werden muss, wird geladen, wenn die Ansicht erstellt wird.

Also sagen wir, ich habe eine Methode, um einen Kunden zurückzugeben, und ein Kunde hat eine Reihe von Kontakten und Kontakte haben eine Reihe von Adressen, und so weiter. Wenn ich getCustomer() von meinem neuen "RIA" -Controller aus anrufe, erhält es einen Kunden, aber die Sammlung der Kontakte des Kunden wird nur ein Proxy oder Null sein.

Ich könnte eine neue Ebene über das, was ich bereits habe, die DTOs zurückgibt, die bereits ausgefüllt sind ... aber ... das scheint, wird es kompliziert werden.

Irgendwelche Ratschläge?

Antwort

2

Sie haben absolut Recht, dass dies ein Problem für RIAs einführt. Wenn Sie OpenSessionInViewFilter verwenden, werden die Daten nicht null zurückgegeben. vielmehr wird der Serializer das gesamte Objektdiagramm durchlaufen und eine enorme Menge an Daten zurücksenden. Dies wird zu ernsthaften Leistungsproblemen führen.

Durch die Einführung eines separaten DTO-Layers erhalten Sie eine Menge Kontrolle, indem Sie sicherstellen, dass der Serializer nur die von Ihnen erstellten Objekte durchläuft. Sie können sicherstellen, dass sie keine faulen Proxys enthalten. Dies führt leider zu einem mühseligen Mapping-Code zwischen Ihren Entitäten und DTOs, aber es gibt Ihnen die volle Kontrolle, um alles zu tun, was Sie wollen.

Ein anderer Ansatz besteht darin, eine Schicht kurz vor dem Serializer einzuführen, die Ihr Objektdiagramm für die Serialisierung vorbereitet. Ein Ansatz, den wir bei einigen früheren Projekten verwendet haben, war die Einführung eines Aspekts in der Service-Schicht, der das gesamte Objektdiagramm durchläuft und Lazy-Proxys durch eine neue Instanz der Entity mit nur der @Id-Eigenschaft ersetzt. Wenn der Graph zu einem späteren Zeitpunkt gespeichert wurde, würde dies sicherstellen, dass @ManyToOne-Beziehungen nicht versehentlich auf Null gesetzt wurden. Sie können Getter aufrufen oder Hibernate.initialize() verwenden, um die Initialisierung von Daten zu erzwingen, die Sie über die Verbindung senden möchten. Dies wird jedoch komplizierter, wenn Sie das kaskadierende Speichern von @OneToMany- oder @ManyToMany-Beziehungen in Hibernate einführen.

Ich bin vor kurzem auf eine Lösung namens Gilead gestoßen, die entwickelt wurde, um mit diesem Problem umzugehen. Es verwendet einen ähnlichen Ansatz wie die oben beschriebenen:

http://noon.gilead.free.fr/gilead/

Ich glaube auch, Granit DS eine Lösung für dieses Problem im Rahmen der Tide Rahmen hat:

http://www.graniteds.org/confluence/display/DOC/4.+Lazy+Initialization

Ein Problem, das ich glaube nicht, dass jemand gelöst hat, ist eine Möglichkeit, Daten in einem RIA tatsächlich vom Server zu laden.Ich denke, es könnte sicherlich getan werden, aber es gibt einige Sicherheitsbedenken hier. Sie müssten eine recht robuste Sicherheitsüberprüfung durchführen, um sicherzustellen, dass alle Versuche, die Daten zu laden, von dem Benutzer stammten, der tatsächlich berechtigt ist, diese Daten überhaupt zu laden.

+0

Vielen Dank! Hast du Erfahrung mit dpHibernate? Ich denke, dass es dieses Problem für mich lösen kann, aber ich bin mir nicht sicher (das heißt, wenn ich Flex verwende). – Boden

+0

Ich habe nicht mit dpHibernate codiert, obwohl ich die Dokumentation überprüft habe. Eine der großen Sorgen, die ich hatte, war, dass es die Sicherheitsfragen nicht anzugehen schien, aber ich habe vielleicht etwas verpasst. –

+0

Können Sie die Sicherheitsbedenken, die Sie haben, genauer erläutern? – Boden

0

Wenn für Ihre Präsentationsschicht die Anwesenheit von Kundenkontakten erforderlich ist, wird diese vom Datenlayer bereitgestellt. Der Zweck von lazy loading besteht darin, Daten nicht wegzulassen ... es wird in der Computerprogrammierung verwendet, um die Initialisierung eines Objekts auf den Zeitpunkt zu verzögern, an dem es benötigt wird.

Sie brauchen sich keine Sorgen zu machen.

+0

Hmm, das macht für mich keinen Sinn. Die Objekte, die ich zurückgebe, werden serialisiert, daher muss alles, was sie enthalten, geladen werden, bevor sie gesendet werden. Wenn ich also eine Methode getCustomer() aufrufen würde und ein Kunde eine Sammlung von beispielsweise Contacts hat, die faul geladen ist, würde das Customer-Objekt zum Zeitpunkt der Serialisierung keine gültige Sammlung von Kontakten enthalten. Wenn der Client getCustomer(). GetContacts() versucht, bekommt er nichts. – Boden

+0

Eigentlich sieht es so aus, als ob meine Bedenken rückgängig gemacht werden könnten - alles wird bei der Serialisierung geladen (zumindest mit den Blazeds von Feder) ... was insgesamt ein anderes Problem darstellt. Siehe folgendes: http://www.infoaccelerator.net/blog/post.cfm/bypassing-hibernate-s-lazy-loading-in-blazeds-with-spring – Boden