2010-07-13 16 views
5

Estoy aprendiendo GAE y estoy un poco atascado. Si utilizo el siguiente, con un fin de asegurarse de que el gestor de persistencia está cerrado, me sale una excepción cuando se trata de leer realmente los nota objetos:¿Cómo se hacen disponibles los resultados de consulta después de cerrar el administrador de persistencia?

public class Notes { 
    public List<Note> getAll() { 
    PersistenceManager pm = PMF.instance().getPersistenceManager(); 

    try { 
     Query query = pm.newQuery("select from com.uptecs.google1.model.Note order by subject"); 
     return (List<Note>) query.execute(); 
    } finally { 
     pm.close(); 
    } 
    } 
} 

La excepción que se ve es la siguiente:

Object Manager has been closed 
org.datanucleus.exceptions.NucleusUserException: Object Manager has been closed 
    at org.datanucleus.ObjectManagerImpl.assertIsOpen(ObjectManagerImpl.java:3876) 
    at org.datanucleus.ObjectManagerImpl.getFetchPlan(ObjectManagerImpl.java:376) 
    at org.datanucleus.store.query.Query.getFetchPlan(Query.java:497) 

Respuesta

9

Trate de extraer el objeto a partir de la gráfica con detachable="true":

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true") 
public class Note { 
    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    private Long key; 
... 
} 

Nota: entiendo totalmente el nee d para esto, a veces necesita recuperar los objetos y las listas en un controlador, cerrar el PM en el controlador y luego pasar los modelos a las vistas. Hasta que conozcan mejores soluciones, esto es lo que estoy haciendo en JDO/GAE sin problemas hasta el momento.

lista:

Me parece que va a tener que desmontar todos los elementos de la lista, si quieres ser capaz de utilizarlas después de la PM se cierra. Yo usaría esto para obtener listas específicas de artículos. Un getAll() completo puede ser muy grande.

public List<Note> getList(){ 
    List<Note> detachedList=null, list=null; 
    try { 
     String query = "select from " + Note.class.getName(); 
     pm = PMF.get().getPersistenceManager(); 
     list = (List<Note>)pm.newQuery(query).execute();    
     detachedList = new ArrayList<Note>(); 
     for(Note obj : list){ 
      detachedList.add(pm.detachCopy(obj)); 
     } 

    } finally { 
     pm.close(); 
    } 
    return detachedList; 

} 

Por Clave:

public Note findByKey(Long key) { 
    Note detachedCopy=null, object=null; 
    try{ 
     pm= PMF.get().getPersistenceManager(); 
     object = pm.getObjectById(Note.class,key); 
     detachedCopy = pm.detachCopy(object); 
    }catch (JDOObjectNotFoundException e) { 
     return null; // or whatever 
    } 
    finally { 
     pm.close(); // close here 
    } 
    return detachedCopy; 

} 

de Afer del cierre, que tiene una copia individual, con la que se puede trabajar.

Referencia: http://www.datanucleus.org/products/accessplatform_1_1/jdo/attach_detach.html

+0

Entiendo esta parte, la parte que no entiendo es que es una lista. ¿Se supone que debo recorrer toda la lista y separar cada elemento? – Jacob

+2

Sí, así fue como lo hice. No pude conseguir que separe una lista, cuando trato de hacerlo obtengo una 'org.datanucleus.jdo.excepciones.ClassNotPersistenceCapableException': La clase" La clase "org.datanucleus.store.appengine.query.StreamingQueryResult" no es persistente. Parece que esto es lo que se debe hacer si desea separar los elementos individuales y cerrar el MP. – bakkal

+0

Tengo que comentar ¡Muchas gracias! ¡Estaba enloqueciendo! –

1

Cuando resultado es devuelto en la lista - objetos se recuperan con pereza (sólo cuando se pide para ellos). Como su administrador de persistencia está cerrado, obtiene una excepción. Al "separar" los objetos, le está diciendo efectivamente al administrador de persistencia que los recupere con entusiasmo.

0

Además de la respuesta de bakkal, diría que es absolutamente necesario el parámetro de anotación detachable="true", de lo contrario, nunca lo conseguirás. Para separar una lista de objetos, también puede usar pm.detachCopyAll(your_query_result_list), que será un poco más rápido que su implementación de la iteración para separar, y le permitirá ahorrar algunas líneas de código. Gracias JDO! ;-) Pero tenga en cuenta que este método requiere un molde explícito de sus resultados.

Aquí está un ejemplo de trabajo que uso actualmente en mi última aplicación (la clave utilizada en la consulta es un codificado String):

pm = PMF.get().getPersistenceManager(); 

Query query = pm.newQuery(TandemSubscription.class); 
query.setFilter("groupSubscriptionKey==groupSubscriptionKeyParam"); 
query.setOrdering("dateRDV desc"); 
query.declareParameters("String groupSubscriptionKeyParam"); 

// Get Data 
@SuppressWarnings("unchecked")   
List<TandemSubscription> savedSubscriptions = 
    (List<TandemSubscription>) query.execute(Key); 

// Detach all objects in the list 
savedSubscriptions = 
    (List<TandemSubscription>) pm.detachCopyAll(savedSubscriptions); 

pm.close(); 

// Now you can use the list and its content. 

Espero que esto ayude un poco.

Cuestiones relacionadas