12 Stimmen

AppEngine-Datenspeicher: "Objekt mit der ID ... wird von einem anderen Objektmanager verwaltet"

Ich verwende die Google AppEngine, mit Java. Wenn ich einige Funktionen des Datenspeichers verwende, erhalte ich eine Fehlermeldung:

Object with id "edvaltt.Teacher@64064b" is managed by a different Object Manager

Ich weiß nicht, was das bedeutet, wie ich es beheben kann oder wo ich eine Dokumentation zu diesem Fehler finden kann. Kann mir jemand helfen? Der Code, den ich verwende, lautet:

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class School {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private String shortname;

@Persistent
private String fullname;

@Persistent
@Order(extensions = @Extension(vendorName="datanucleus", key="list-ordering", value="code asc"))
private List<Teacher> Teachers;

...

public Teacher FindOrCreateTeacher(String code)
{
    // Can we find the teacher without any database code?
    Teacher newTeacher = FindTeacher(code);
    if (newTeacher != null)
        return newTeacher;

    // Create the teacher:
    PersistenceManager pm = PMF.get().getPersistenceManager();
    Transaction tx = pm.currentTransaction();
    try {
        tx.begin();
        for (Teacher teacher : Teachers) {
            if (teacher.getCode() == code) {
                tx.rollback();
                return teacher;
            }
        }
        newTeacher = new Teacher(code);
        Teachers.add(newTeacher);
        pm.makePersistent(newTeacher);
        pm.makePersistent(Teachers);
        tx.commit();
    } finally {
        tx.commit();
    }
    return newTeacher;
}

Ich glaube, dass " private List<Teacher> Teachers; " bezieht sich auf eine Beziehung "von einem zu vielen".

9voto

DataNucleus Punkte 15309

Ein persistentes Objekt kann nur von einem PersistenceManager "verwaltet" werden. In DataNucleus wird dies intern durch einen "ObjectManager" unterstützt. Die Meldung besagt, dass Sie versuchen, ein von einem PM verwaltetes Objekt mit einem anderen PM zu verknüpfen. Sie können das leicht debuggen, indem Sie den PM für jedes (persistente) Objekt ausdrucken

JDOHelper.getPersistenceManager(obj);

Da Sie nicht definieren, woher die Nachricht kommt, kann nicht viel mehr gesagt werden. Die DataNucleus-Protokolleinträge würden Ihnen viel mehr verraten als das.

Das Schließen des PM ist immer eine wichtige Sache (es sei denn, Sie wollen Ressourcenlecks)

0 Stimmen

Können Sie mir näher erläutern, was eine geeignete Lebensdauer für eine PM-Instanz ist? Angenommen, ich schreibe eine Webanwendung. Sollte ich sie bei jeder Seitenanforderung öffnen und schließen? Oder sollte ich eine Instanz für die gesamte Lebensdauer des Prozesses offen halten? (Wenn ich eine Transaktion festschreibe, aber das PM nicht schließe, bedeutet das, dass schlimmstenfalls ein Speicherleck entsteht? Ich meine, meine Daten sind sicher?)

1 Stimmen

Wie lange dauert der Prozess? Ein typisches Websystem würde ein PM pro Anfrage verwenden. Die Erstellung eines PM ist nicht teuer (die Erstellung eines PMF ist teuer). Wenn Sie txns verwenden, können Sie ein PM offen lassen, solange Sie nicht auch nichttransaktionale Aktualisierungen mit diesem PM durchführen.

3voto

VonC Punkte 1117238

Wie illustriert in dieses Ticket sollten Sie die pm nicht schließen ( PersistenceManager )?

} finally {
    tx.commit();
    pm.close();
}

0 Stimmen

Ursprünglich dachte ich, dass damit mein Problem gelöst sei, aber das ist nicht der Fall. Erstens weiß ich immer noch nicht, was los ist und warum das Schließen des Persistenzmanagers notwendig ist, oder wann es geschehen soll. Zweitens empfiehlt die AppEngine-Dokumentation die Verwendung eines Singleton-Musters mit dem PersistenceManager, und pm.close() würde bedeuten, dass man für den Rest des Prozesses nichts mehr mit dem Google-Datenspeicher machen kann.

0 Stimmen

Singleton-Muster mit dem PMF, nicht mit dem PM. pm.close() no pmf.close()

2voto

Daghan --- Punkte 1158

DataNucleus,

Vielen Dank für die pm.close(); Tipp. Ich habe eine Abfrage mit einem em

em = EMF.get().createEntityManager();

und einen Commit mit einem anderen zu machen, ohne den ersten zu schließen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X