2010-07-13 4 views
5

Sto imparando GAE e sto diventando un po 'bloccato. Se uso il seguente, con un fine per assicurarsi che il gestore di persistenza è chiuso, ottengo un'eccezione quando si cerca di leggere in realtà gli oggetti Nota:Come rendere i risultati delle query disponibili dopo aver chiuso il gestore di persistenza

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(); 
    } 
    } 
} 

L'eccezione che ottengo è questo:

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) 

risposta

9

Prova staccando l'oggetto dal grafico con detachable="true":

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

Nota: capisco perfettamente la nee Per questo motivo, a volte è necessario recuperare gli oggetti e gli elenchi in un controller, chiudere il PM nel controller, quindi passare i modelli alle viste. Fino a quando mi saranno conosciute soluzioni migliori, questo è quello che sto facendo su JDO/GAE senza problemi fino ad ora.

listino:

Mi sembra che si dovrà staccare tutti gli elementi della lista, se si vuole essere in grado di usarli dopo che il PM è chiusa. Lo userei per ottenere elenchi specifici di elementi. Un full getAll() può essere di dimensioni molto grandi.

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; 

} 

By chiave:

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; 

} 

Afer la chiusura, si dispone di una copia indipendente, con cui è possibile lavorare.

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

+0

Capisco questa parte, il bit che non capisco è che è una lista. Dovrei ripetere l'intera lista e staccare ogni elemento? – Jacob

+2

Sì, è così che ci sono andato. Non riuscivo a staccare una lista, quando provo a farlo ottengo un 'org.datanucleus.jdo.exceptions.ClassNotPersistenceCapableException': La classe" La classe "org.datanucleus.store.appengine.query.StreamingQueryResult" non è persistibile. Sembra che questo sia ciò che deve essere fatto se si desidera che i singoli elementi vengano staccato e chiuso il PM. – bakkal

+0

Devo commentare. Grazie mille! Stavo impazzendo !!! –

1

Quando risultato viene restituito nella lista - gli oggetti vengono recuperati pigramente (solo quando si chiede per loro). Dal momento che il tuo gestore di persistenza è chiuso ottieni un'eccezione. "Staccando" gli oggetti stai dicendo efficacemente al manager di persistenza di recuperarli con entusiasmo.

0

Oltre alla risposta di bakkal, direi che è assolutamente necessario il parametro di annotazione detachable="true", altrimenti non lo farai mai funzionare. Per staccare un elenco di oggetti, puoi anche usare pm.detachCopyAll(your_query_result_list), che sarà un po 'più veloce dell'implementazione dell'iterazione da staccare, e ti permetterà di risparmiare qualche riga di codice. Grazie JDO! ;-) Ma attenzione, questo metodo richiede il cast esplicito dei suoi risultati.

Ecco un esempio di lavoro attualmente utilizzo nel mio ultimo App (la chiave utilizzato nella query è una stringa codificata):

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. 

Spero che questo aiuta un po '.

Problemi correlati