2010-11-15 15 views
5

Tengo dos preguntas sobre cómo crear/usar el administrador de persistencia de JDO (PM, en lo sucesivo).¿Cómo usar el administrador de persistencia JDO?

Say, en una aplicación web Java, si tengo 10 entidades, que pueden ser agrupados de forma lógica en 2 grupos (por ejemplo, 5 entidades relacionados con el usuario y 5 entidades relacionadas con el negocio)

  1. si necesito dos diferentes PM para administrar estos 2 grupos o solo un PM es suficiente?
  2. En cuanto a la inicialización, ¿debo usar una instancia única de un PM (que será compartida por todos los usuarios que usan la aplicación en un momento dado) o debería crear un PM para cada sesión?

Respuesta

14

De acuerdo con JDO Documentation, crea uno PersistenceManagerFactory por almacén de datos. Si está utilizando JDO para acceder a las bases de datos a través de SQL y tiene más de una base de datos, necesitará una PersistenceManagerFactory por base de datos (ya que debe especificar la URL JDBC, nombre de usuario y contraseña al crear el PersistenceManagerFactory).

Para casos de uso simple, puede simplemente crear un PersistenceManager cuando lo necesite y cerrarlo en una cláusula finally (consulte the persistence manager documentation).

Si usa transacciones, y el código para actualizar entidades se puede dividir en varios métodos u objetos, recomiendo crear el PersistenceManager bajo demanda y almacenarlo en un ThreadLocal (o un objeto con ámbito de solicitud si usa Guice o Spring) . Esto asegurará que cualquier código que haga actualizaciones participe en la transacción actual. Asegúrese de cerrar el PersistenceManager al final de la solicitud.

Si sólo necesita una fábrica gestor de persistencia, que puede hacer:

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

Cualquier código que necesita un gestor de persistencia puede llamar Datastore.getPersistenceManager()

Nota: He utilizado todos los métodos estáticos para que sea sencillo para el propósito de responder tu pregunta Si estuviera usando un framework de inyección de dependencias como Guice, haría los métodos no estáticos y vincularía Datastore como Singleton.

Se podría llamar finishRequest en un filtro de 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

gracias por una respuesta tan detallada. – Veera

+0

Un problema: hacer una búsqueda/reemplazo y cambiar todas las apariciones de 'persistAnce' a 'persistEnce' y usted será mucho más feliz. :-) – TOB

+0

Encontré que este enfoque no funciona en el motor de aplicaciones de Google, por cualquier razón funciona perfectamente en localhost pero el pmf está cerrado en momentos inesperados en la producción – bsautner

Cuestiones relacionadas