2012-06-24 687 views
26

El idioma habitual que veo para crear el EntityManager es algo como esto:maneras diferentes de conseguir el EntityManager

public class BaseDao { 

private static final String PERSISTENCE_UNIT_NAME = "Employee"; 
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 

public EntityManager getEntityManager() { 
     return factory.createEntityManager(); 
    } 
} 

continuación, se utiliza la siguiente manera:

Employee emp = new Employee(); 
emp.setName("Joe M"); 
getEntityManager().persist(emp); 

La pregunta es ¿por qué no hacerlo de esta manera:

public class BaseDao{ 
    private static final String PERSISTENCE_UNIT_NAME = "Employee"; 
    EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
    private EntityManager entityManager = null; 


public void setEntityManger() { 
     EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
    this.entityManager = factory.createEntityManager(); 

    } 

    public EntityManager getEntityManager() { 
     return this.entityManager; 
    } 
} 

En otras palabras, existe la necesidad de obtener siempre el administrador de entidades a través de factory.crea teEntityManager()? o puede crearse como una variable de instancia (o incluso estática) y recuperarse así?

Para aclarar, me refiero a un entorno que no utiliza contenedores EJB o Spring.

Gracias.

Respuesta

10

Hay dos formas de crear instancias EntityManager. Una forma es para aplicaciones SDK, y lo uso mucho en pruebas unitarias. Esto es lo que tienes en tu ejemplo:

EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 

en aplicaciones empresariales deja que el recipiente de las cree e inyectarlos cuando sea necesario.

EntityManager es solo una envoltura alrededor de una conexión JDBC. Es muy ligero y se puede crear y destruir sin penalización de rendimiento.

Tenga en cuenta que el EntityManager no es seguro para subprocesos, por lo que si tiene una instancia, es posible que deba sincronizar el acceso al mismo. Vea transaction basics para más detalles.


Así es como yo lo haría (más o menos):

public class BaseDao{ 
    private static final String PERSISTENCE_UNIT_NAME = "Employee"; 
    private static EntityManagerFactory factory = 
    Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 

    public void create(MyEntiy person){ 
    EntityManager em = factory.createEntityManager(); 
    em.getTransaction().begin(); 
    // do what ever you need 
    em.getTransaction().commit(); 
    em.close(); 
    } 

    // add more methods to the dao. 
} 

Una vez que este protoyped y listo, se puede utilizar un DAO genérico.

+0

gracias - Agregué una nota a mi publicación original aclarando que no estoy en un entorno empresarial, por lo tanto, la inyección de contenedor no está disponible. Sin embargo, sí he notado tu comentario sobre la seguridad de las hebras. – jayjay

+0

RE thread-safety - Supongo que se refiere a mi ejemplo, ya que un EntityManager inyectado y administrado por un contenedor sería seguro para subprocesos. – jayjay

+0

No, no será seguro para subprocesos, pero el contenedor crea uno nuevo cuando sea necesario (podría estar equivocado), por lo que parece que es seguro para subprocesos. Si no está en ningún entorno empresarial, entonces no veo ningún problema en crear una instancia estática de fábrica EntityManagerFactory, y lo llamo para obtener instancias de EntityManager cuando sea necesario. Y no olvide cerrarlos después de cada transacción. Este hilo muestra un código que puede ser útil para usted. http://stackoverflow.com/questions/7329873/how-should-manage-database-transactions-using-entity-manager-in-a-relatively-lar – Mansour

0

Hoy probablemente deberías consultar alguna vez como spring-data y @PersistanceUnit para administrar tu EntityManager.

Un EntityManager es más que un contenedor para una conexión JDBC. Define el alcance de un contexto de persistencia, que define la unidad de trabajo que se debe realizar cuando se compromete una transacción (de cuando realiza consultas en la base de datos). Dentro de un contexto de persistencia también se le garantiza que una entidad dada en la base de datos dará como resultado el mismo objeto Java, independientemente de si lo carga directamente, o si tiene acceso a través de una relación OneToMany de otra entidad.

Con respecto a la pregunta original sobre la obtención de una EntityManagerFactory en una configuración sin resorte. Sólo tiene que llamar

Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 

Este método es un método de fábrica estática, dependiendo de la implementación de la APP que o bien obtener la misma instancia de la misma PU, o una envoltura superficial que envuelve la persistencia de sesión subyacente (de los cuales hay uno por PU).

Cuestiones relacionadas