2010-11-15 6 views
5

Ho due domande su come creare/utilizzare il gestore di persistenza JDO (PM, in futuro).Come utilizzare il gestore di persistenza JDO?

Say, in un'applicazione Web Java, se ho 10 soggetti, che possono essere raggruppate in 2 gruppi (ad esempio, 5 entità relativi utenti e 5 le entità di business correlati)

  1. dovrebbe ho bisogno di due sono sufficienti PM diversi per gestire questi 2 gruppi o solo un PM?
  2. Per quanto riguarda l'inizializzazione, devo utilizzare l'istanza singleton di un PM (che verrà condivisa da tutti gli utenti che utilizzano l'app in un determinato momento) o dovrei creare un PM per ogni sessione?

risposta

14

In base allo JDO Documentation si crea uno PersistenceManagerFactory per datastore. Se si utilizza JDO per accedere ai database tramite SQL e si dispone di più database, sarà necessario uno PersistenceManagerFactory per database (poiché è necessario specificare l'URL JDBC, il nome utente e la password quando si crea lo PersistenceManagerFactory).

Per casi d'uso semplici, è sufficiente creare uno PersistenceManager quando necessario e chiuderlo in una clausola finally (vedere the persistence manager documentation).

Se si utilizzano le transazioni, e il codice per l'aggiornamento entità possono essere distribuite su metodi multipli o oggetti, si raccomanda di creare il PersistenceManager on demand e riporlo in un ThreadLocal (oggetto o richiesta con ambito se si utilizza Guice o primavera) . Ciò assicurerà che qualsiasi codice che fa gli aggiornamenti partecipi alla transazione corrente. Assicurati di chiudere lo PersistenceManager alla fine della richiesta.

Se avete solo bisogno di una fabbrica di persistenza manager, si può fare:

public class Datastore { 
    private static PersistenceManagerFactory PMF; 
    private static final ThreadLocal<PersistenceManager> PER_THREAD_PM 
     = new ThreadLocal<PersistenceManager>(); 

    public static void initialize() { 
    if (PMF != null) { 
     throw new IllegalStateException("initialize() already called"); 
    } 
    PMF = JDOHelper.getPersistenceManagerFactory("jdo.properties"); 
    } 

    public static PersistenceManager getPersistenceManager() { 
    PersistenceManager pm = PER_THREAD_PM.get(); 
    if (pm == null) { 
     pm = PMF.getPersistenceManager(); 
     PER_THREAD_PM.set(pm); 
    } 
    return pm; 
    } 

    public static void finishRequest() { 
    PersistenceManager pm = PER_THREAD_PM.get(); 
    if (pm != null) { 
     PER_THREAD_PM.remove(); 
     Transaction tx = pm.currentTransaction(); 
     if (tx.isActive()) { 
     tx.rollback(); 
     } 
     pm.close(); 
    } 
    } 
} 

Qualsiasi codice che ha bisogno di un gestore di persistenza può chiamare Datastore.getPersistenceManager()

Nota: Ho usato tutti i metodi statici per rendere semplice per lo scopo di rispondere alla tua domanda. Se stavo usando un framework di iniezione delle dipendenze come Guice, renderei i metodi non statici e legare Datastore come Singleton.

Si potrebbe chiamare finishRequest in un filtro Servlet:

public class PersistenceManagerFilter implements javax.servlet.Filter { 

    public init(FilterConfig filterConfig) { 
    Datastore.initialize(); 
    } 

    public void doFilter(ServletRequest request, 
     ServletResponse response, FilterChain chain) 
     throws IOException, ServletException { 
    try { 
     chain.doFilter(request, response); 
    } finally { 
     Datastore.finishRequest(); 
    }  
    } 
} 
+0

grazie per una risposta così dettagliata. – Veera

+0

Un problema: fai una ricerca/sostituisci e cambia tutte le occorrenze di "persistAnce" in "persistEnce" e sarai molto più felice. :-) – TOB

+0

Ho trovato questo approccio non funziona su Google App Engine - per qualsiasi motivo funziona perfettamente su localhost ma il pmf è chiuso a orari imprevisti in produzione – bsautner