2009-06-28 6 views
21

Ich habe gerade angefangen, Google Web Toolkit zu lernen und habe die Stock Watcher-Tutorial-App fertig geschrieben.Senden von persistenten JDO-Instanzen über GWT-RPC

Ist meine richtig zu denken, dass wenn man ein Business-Objekt (wie ein Lager) anhalten will JDO verwendet und es hin und her zu/von dem Client über RPC sendet dann ein zwei separate Klassen erstellen hat für dieses Objekt: Eine mit den JDO-Annotationen für das Fortbestehen auf dem Server und eine andere, die serialisierbar ist und über RPC verwendet wird?

bemerke ich die Auf Watcher separate Klassen hat und ich kann theoretisieren, warum:

  • Ansonsten ist der GWT-Compiler versuchen würde die persistente Klasse für alles wie JDO und com.google.blah verwiesen Javascript zu erzeugen .users.User, etc
  • Auch gibt es möglicherweise Logik auf der Server-Seite Klasse, die nicht auf den Client und umgekehrt gilt.

Ich möchte nur sicherstellen, dass ich das richtig verstehe. Ich möchte nicht zwei Versionen aller meiner Geschäftsobjektklassen erstellen müssen, die ich über RPC verwenden möchte, wenn ich nicht haben muss.

Antwort

0

Sie müssen keine separaten Instanzen erstellen, in der Tat ist es besser, wenn Sie es nicht tun. Ihre JDO-Objekte sollten sowieso normale POJOs sein und sollten niemals Geschäftslogik enthalten. Das ist für Ihre Business-Schicht, nicht Ihre persistenten Objekte selbst.

Alles, was Sie tun müssen, ist die Quelle für die Anmerkungen, die Sie verwenden, und GWT sollte Ihre Klasse gut kompilieren. Außerdem sollten Sie keine Bibliotheken verwenden, die GWT nicht kompilieren kann (wie Dinge, die Reflektionen verwenden, usw.), aber in all den Projekten, die ich gemacht habe, war das nie ein Problem.

+1

Das Problem ist nicht, dass er die Geschäftslogik in seinen JDOs hat, ist es die JDO-Annotationen, die Probleme verursachen (weil GWT keinen Zugriff auf die Quelle hat, wie Sie darauf hinweisen). Dies ist ein großes Problem in GWT + GAE, und ich wünschte, Google würde eine angemessene Lösung artikulieren. –

2

Ihre Einschätzung ist richtig. JDO ersetzt Instanzen von Sammlungen durch eigene Implementierungen, um zu schnüffeln, wenn sich der Objektgraph ändert, nehme ich an. Diese Implementierungen sind dem GWT-Compiler nicht bekannt und können daher nicht serialisiert werden. Dies tritt häufig bei Klassen auf, die aus ansonsten GWT-konformen Typen bestehen, jedoch mit JDO-Annotationen, insbesondere wenn einige der Objekteigenschaften Collections sind.

Eine detaillierte Erklärung und dieses Problem zu umgehen, lesen Sie in diesen ziemlich einflussreichen Aufsatz zum Thema: http://timepedia.blogspot.com/2009/04/google-appengine-and-gwt-now-marriage.html

+2

JDO ersetzt Collections nicht durch eigene Implementierungen. DataNucleus zum Beispiel hat eine Option, genau das zu tun, aber die Standardeinstellung ist die Verwendung von java.util. * - Klassen, so dass wir dem Benutzer nicht auferlegen, DataNucleus auf der Client-Seite zu haben. – DataNucleus

4

Die kurze Antwort lautet: Sie müssen nicht erstellen doppelte Klassen.

Ich empfehle Ihnen, einen Blick aus der folgenden Google-Gruppen Diskussion über die Liste GWT-Beiträger nehmen:

http://groups.google.com/group/google-web-toolkit-contributors/browse_thread/thread/3c768d8d33bfb1dc/5a38aa812c0ac52b

Hier ist ein interessanter Auszug:

Wenn dies alles, was Sie Bin interessiert, ich beschrieben eine Möglichkeit, GAE und GWT-RPC zusammenarbeiten "aus der Box".erklären Sie einfach Ihre Entitäten wie: @PersistenceCapable (identity = IdentityType.APPLICATION, abnehmbare = "false") public class MyPojo Serializable implementiert {}

und alles funktioniert, aber Sie werden manuell behandeln erneut anhängen, wenn Objekte vom Client zurück an den Server gesendet werden.

Sie können diese Option verwenden, und Sie benötigen keine Spiegel (DTO) -Klasse. Sie können auch versuchen, gilead (ehemals Hibernate4gwt), die einige Details in den Problemen der Serialisierung von erweiterten Objekten kümmert.

1

Sie müssen nicht zwei Versionen des Domänenmodells erstellen.

Hier sind zwei Tipps:

einen String kodierte Schlüssel verwenden, nicht die appengine Key-Klasse.

pojo = pm.detachCopy(pojo) 

... werden alle JDO-Erweiterungen entfernt.

2

Ich habe endlich eine Lösung gefunden. ändern Sie Ihr Objekt überhaupt nicht, aber für die Auflistung tun es auf diese Weise:

List<YourCustomObject> secureList=(List<YourCustomObject>)pm.newQuery(query).execute(); 
return new ArrayList<YourCustomObject>(secureList); 

Das eigentliche Problem ist nicht in Serialisierung das Objekt ... das Problem ist die Collection-Klasse zu serialisieren, die von Google implementiert und darf nicht serialisiert werden.

0

Ich denke, dass ein besseres Format zum Senden von Objekten durch GWT über JSON ist. In diesem Fall würde vom Server ein JSON-String gesendet, der dann im Client geparst werden müsste. Der Vorteil ist, dass das endgültige Javascript, das im Browser gerendert wird, eine kleinere Größe hat. Dadurch wird die Seite schneller geladen.

Zweitens, um Objekte über GWT zu senden, sollten die Objekte serialisierbar sein. Dies kann nicht der Fall sein, für alle Objekte

Drittens GWT Funktionen Inbuilt hat JSON zu handhaben ... so keine Probleme auf dem Client-Ende

+0

es ist wahr, dass das Senden von JSON den Deal vereinfacht, aber es beseitigt auch ein großartiges Feature von GWT: das gleiche Objektmodell auf Client & Server zu haben, ohne die Mühe der Hand Serialisierung zu schreiben. –