2012-04-03 8 views
0

Ich hätte gerne eine Beziehung zwischen zwei persistence-fähigen Klassen, die auf einmal erstellt wurden. Die Beziehung muss nicht verwendet werden, da meine App nicht wirklich garantieren kann, dass die beiden Instanzen, die ich beibehalten möchte, für immer in derselben Entitätsgruppe bleiben. Meine Beziehung ist eine bidirektionale One-to-many:JDO, unverheiratete Beziehung und mehrere Objekte gleichzeitig beibehalten

// in first class 
@Persistent 
private Set<Key> instancesOfSecondClass; 

// in second class 
@Persistent 
private Key instanceOfFirstClass; 

Dann in einem Servlet doPost() Anruf, ich brauche eine Instanz pro diesen Klassen bestehen bleiben. Ich habe tatsächlich eine nette Methode entwickelt, um beide Seiten der Beziehung aufrecht zu erhalten. Zunächst wird der Key id (ich verwende ...

@PrimaryKey 
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
private Key id; 

... als Primärschlüssel überall) mit dem Set in dem ersten Klasse hinzugefügt wird, dann eine bequeme Methode auf der Instanz der zweiten Klasse mit dem Namen dieser Änderung und Aktualisierung benachrichtigen die eine Schlüsseleigenschaft dementsprechend, alte Werte, Nullkontrollen und alles vergleichend. Tatsächlich habe ich noch keinen Schlüssel, wenn die Instanz frisch ist, also muss ich sie beide zuerst mit pm.makePersistent() aufrufen, dann mache die Zuweisung und warte auf pm.close(), um später zu geschehen.

Aber was wirklich passiert, ist ziemlich verwirrend. Nach dem Ausführen des Servlet (deren alleiniger Zweck es ist serialisiert Key s dieser beiden Instanzen für den Einsatz an anderer Stelle zurückzukehren), gehe ich auf den Datenspeicher-Viewer überprüfen und sehen:

  • die Instanz von der ersten Klasse beibehalten wurde (eigentlich ein mehr Problem hier bei mir zu werfen NullPointerException von org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.postInsert(PersistenceCapableMapping.java:1039) in dem Moment, ich pm.makePersistent() auf der Instanz mit Set<Key> nennen)
  • die Instanz der zweiten Klasse beibehalten wurde (so weit so gut)
  • die Instanz der zweiten Klasse hat den Key Bezug auf die erste Instanz blieb bestehen, yay
  • der Satz von Tasten auf der ersten Instanz ist ... warten Sie ... leer

Der lokale Datenspeicher zeigt nur leeren Raum, während die ein Online-<null> zeigt, obwohl mein Konstruktor für die Klasse (eine Eins mit Argumente) erstellt eine neue Instanz von HashSet<T> für die Beziehung.

Mit Google App Engine für Java 1.6.4, passiert auch in 1.6.3.

verbrachte einen ganzen Tag versucht, dies zu lösen, setzen Transaktionen dazwischen, mit zwei PersistenceManager s, verschiedene Reihenfolge der persistenten Anrufe, gruppenübergreifende Transaktionen ermöglichen, half nichts.

Generisch würde ich glücklich sein, eine funktionierende Möglichkeit zu finden, zwei Instanzen in zwei separaten Entitätsgruppen mit unbekannter Beziehung zwischen ihnen zu erstellen und zu aktualisieren, unabhängig von der möglichen Inkonsistenz (macht mir nicht so viel Sorgen, basierend auf der Häufigkeit der möglichen Aktualisierungen).

In der Zwischenzeit habe ich zwei weitere mögliche Lösungen gefunden, habe sie aber noch nicht ausprobiert: 1. Erstelle nicht nur zwei, sondern vier PersistenceManager s (eins zum Erstellen der ersten Instanz, zweites zum Erstellen der zweiten Instanz, drittes zum Aktualisieren Sie eine Seite der Beziehung, viertes, um die zweite Seite der Beziehung zu aktualisieren), oder 2. trennen Sie die Instanzen und machen Sie sie nach dem Update wieder persistent. Ich bin mir nicht sicher, welchen Weg ich jetzt gehen sollte.

+0

Oder vielleicht eine dritte mögliche Lösung, die rechtzeitige one: upgrade auf das neueste DataNucleus plugin 2.0? – themarketka

+0

Scheint, ich habe mich geirrt, dass die Transaktionen nicht funktionieren, ich habe sie einfach falsch benutzt. Jetzt habe ich eine Menge 'TXN = pm.currentTransaction();' ' txn.begin();' ' // das Update Teilwerk' ' txn.commit(); ' um die Updates (erstellen Sie zuerst Instanz, zweite Instanz erstellen, Beziehung aktualisieren - aufgrund der Verwendung gruppenübergreifender Transaktionen reicht hierfür eine Transaktion aus. Sollte das früher gefunden haben. Wie auch immer, die Tatsache, dass App Engine keinerlei Nebenläufigkeitsprobleme gemeldet hat, macht mir Sorgen und hat mich einen ganzen Tag lang an ein eigentlich einfaches Problem gehängt. Wenn es nur eine Ausnahme oder etwas warf ... – themarketka

+0

Und die v2 des Plugins bietet "echte" unreowned Beziehungen, anstatt hvaing, um einen Schlüssel und einen Satz von Schlüssel dort – DataNucleus

Antwort

1

v2 des Plugins bietet "echte" unangekündigte Beziehungen mit keiner dieser Schlüssel Hacker zuvor benötigt.Sie können beide Seiten in der gleichen Transaktion beibehalten, wenn das Flag für mehrere Entitätsgruppen gesetzt ist, oder Sie können sie nicht-transaktional beibehalten.

Gerade bei den Tests für Ideen http://code.google.com/p/datanucleus-appengine/source/browse/trunk/tests/com/google/appengine/datanucleus/jdo/JDOUnownedOneToManyTest.java

Ich habe keine Kontrolle darüber, was in ihre docs geht, nur geht, was in ihrem Code ;-)

+0

Danke :-) Ist das v2-Plugin schon so zuverlässig für eine einfache Benutzung, dass ich den Code für die Produktion aktualisieren kann? Ich glaube, ich habe in der Dokumentation gesehen, dass nackte Beziehungen von vielen zu vielen noch nicht funktionieren, aber ich werde sie auch brauchen. – themarketka

+0

es besteht alle GAE-Tests, die sie vorher hatten, und alle Tests, die ich seitdem hinzugefügt habe, also ja. In ihren Dokumenten haben sie normalerweise einen Abschnitt weiter unten auf der Seite und sagen, dass im v2-Plugin einige andere Dinge jetzt unterstützt werden. – DataNucleus

Verwandte Themen