2009-09-10 12 views
12

Estoy usando Google AppEngine, con Java. Cuando utilizo algunas de las características del almacén de datos, estoy recibiendo un mensaje de error:AppEngine datastore: "Objeto con id ... es administrado por un Administrador de Objetos diferente"

Object with id "[email protected]" is managed by a different Object Manager 

No sé lo que esto significa o cómo solucionarlo o dónde buscar documentación sobre este error. ¿Alguien puede ayudarme? El código que estoy usando es:

@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; 
} 

creo que "private List<Teacher> Teachers;" se refiere a una "propiedad, uno a muchos" relación.

Respuesta

9

Un objeto persistente sólo puede ser "manejado" por uno PersistenceManager. En DataNucleus esto es respaldado internamente por un "ObjectManager". El mensaje dice que está tratando de asociar un objeto administrado por un PM con un PM diferente. Se puede depurar fácilmente que imprima la PM para cada objeto (persistente)

JDOHelper.getPersistenceManager(obj); 

Ya que no definen en el que el mensaje viene de, no mucho más se puede decir. Las entradas de registro de DataNucleus te dirían mucho más que eso.

el cierre de la PM es siempre una cosa esencial que ver (a menos que desee pérdidas de recursos)

+0

Explicación interesante. +1 – VonC

+0

¿Puede explicarme qué duración es adecuada para una instancia de PM? Supongamos que estoy escribiendo una aplicación web. ¿Debo abrirlo y cerrarlo en cada solicitud de página? ¿O mantener una instancia abierta durante toda la vida del proceso? (Si realizo una transacción pero no cierro el MP, ¿significa esto que lo peor que ocurre es una pérdida de memoria? ¿Quiero decir que mis datos están seguros?) –

+1

¿Cuánto dura el proceso? Un sistema web típico usaría un PM por solicitud. Crear un PM no es costoso (crear un PMF * es * costoso). Si usa txns, puede dejar un PM abierto de forma segura ... siempre que no realice actualizaciones no transaccionales también con ese PM. – DataNucleus

3

Como se ilustra en this ticket, ¿no debería cerrar el pm (PersistenceManager)?

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

Originalmente pensé que esto había resuelto mi problema, pero no es así. Para empezar, todavía no sé qué está sucediendo y por qué es necesario cerrar el administrador de persistencia o cuándo se debe hacer. En segundo lugar, la documentación de App Engine alienta el uso de un patrón singleton con PersistenceManager, y pm.close() significa que no se puede hacer nada más con el almacén de datos de Google durante el resto del proceso. –

+0

Patrón Singleton con el PMF, no el PM. pm.close() * not * pmf.close() – DataNucleus

2

DataNucleus,

Gracias por la punta pm.close();. yo estaba haciendo una consulta con uno em

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

y hacer un commit con otro sin cerrar la primera.

Cuestiones relacionadas