java - que - jpa
diferentes formas de obtener el EntityManager (2)
La expresión habitual que veo para crear EntityManager es algo como esto:
public class BaseDao {
private static final String PERSISTENCE_UNIT_NAME = "Employee";
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
public EntityManager getEntityManager() {
return factory.createEntityManager();
}
}
entonces se usa así:
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.createEntityManager ()? o puede crearse como una variable de instancia (o incluso estática) y recuperarse así?
Para aclarar, estoy hablando de un entorno que no usa contenedores EJB o Spring.
Gracias.
Hay dos formas de crear instancias de 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 las aplicaciones empresariales, permite que el contenedor las cree y las inyecte cuando sea necesario.
EntityManager
es solo un contenedor alrededor de una conexión JDBC. Es muy ligero y se puede crear y destruir sin penalización de rendimiento.
Tenga en cuenta que EntityManager
no es seguro para subprocesos, por lo que si tiene una instancia, es posible que deba sincronizar el acceso a ella. Ver aspectos básicos de las transacciones para más detalles.
Así es como 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 obtenga este protoyped y listo, puede usar un DAO genérico.
Hoy probablemente deberías mirar en algún momento 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. Simplemente llama
Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
Este método es un método de fábrica estático. Dependiendo de la implementación de su JPA, obtendrá la misma instancia para la misma PU o una envoltura superficial que envuelva la sesión de persistencia subyacente (de la que hay una por PU).