Pregunta

Tengo un par de preguntas relacionadas con el uso del gestor de la entidad en un entorno JavaSE.

Estoy usando el patrón de repositorio para realizar mis operaciones CRUD en la base de datos. Habrá una clase repositorio de base de este modo:

public class Repository<T> implements IRepository<T> {

    private EntityManager em;
    private String persistenceUnitName;

    public Repository(String persistenceUnitName) {
        this.persistenceUnitName = persistenceUnitName;
    }

    @Override
    public T find(Class<T> type, Object id) {
        return em.find(type, id);
    }

    private EntityManager getEntityManager() {
        if (this.em == null) {
            EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);

            em = emf.createEntityManager();
        }

        return em;
    }
    ...
    ...
}

Entonces tendrá clases como EmployeeRepository que heredarán Repositorio. Estas clases de repositorios se crearán en mi capa de servicio.

¿Es esta una buena manera de inicializar el gestor de la entidad? Estoy empezando a pensar que no es - parece que sólo se debe tener uno gestor de la entidad por unidad de persistencia? Cuando, como en este caso, tendría un gestor de la entidad para cada repositorio se crea ... ¿Cómo haría usted para asegurar que sólo tiene un gestor de la entidad por unidad de persistencia? Además, he notado que los métodos gestor de la entidad y gestor de la entidad de fábrica tienen una estrecha método - cuando éstos deben ser llamados? En un servidor de terminar evento?

Si sabes de algún fuentes buenas de usar JPA en JavaSE le agradecería la información.

Gracias!

¿Fue útil?

Solución

Casi. Sólo se necesita una EntityManagerFactory por unidad de persistencia.

  

¿Cómo haría usted para asegurar que sólo tiene una EntityManagerFactory por unidad de persistencia?

Por lo general, los desarrolladores crean una clase de ayuda con un producto único EntityManagerFactory como

public class EntityManagerFactoryHelper {

    private static EntityManagerFactory factory;

    static {
        try {
           // Set up factory right here
        } catch(ExceptionInInitializerError e) {
            throw e;
        }
    }

    public static EntityManagerFactory getFactory() {
        return this.factory;
    }

}

EntityManager , en otra parte, se utiliza para interactuar con un conjunto de instancias de entidades gestionadas llamados contexto de persistencia.

Si quieres saber por qué yo uso ErrorInInitializerError , su API está claro

  

Las señales que una excepción inesperado se ha producido en un estática inicializador

...

  

¿Es esta una buena manera de inicializar el gestor de entidades?

Bueno, la capa de servicio se utiliza para delimitar transacciones límite . Así para cada caso de uso usted puede crear su EntityManager y paso por referencia para cada colaborador necesaria para ayudarle a ejecutar su caso de uso.

public static br.com.helper.EntityManagerFactoryHelper.getFactory;

public EmployeeService {

    public void doSomething() {
        EntityManager eManager = getFactory().createEntityManager();
        eManager.getTransaction().begin();

        EmployeeRepository repository = new EmployeeRepository(eManager);

        eManager.getTransaction().commit();
    }

}

Ahora imagina que necesita el código repetitivo mostrado anteriormente para cada caso de uso.

    public void forEachUseCase() {
        // Create an EntityManager
        // Begin a Transaction

        EmployeeRepository repository = new EmployeeRepository(eManager);

        // And finally, commit
    }

Se puede confiar en la primavera para ayudarle para deshacerse de este código repetitivo.

Otros consejos

Brian,

Es bien compartir EntityManagerFactory, pero no está bien para compartir EntityManager. Vea la Java Persistence wikilibro .

Un enfoque más moderno sería hacer únicos con enumeraciones. Por lo tanto, suponiendo que no esperan a la vuelta de cambiar sus nombres de las unidades de persistencia (que se puede esperar que no ocurra en cualquier caso) ...

Así que lo ideal ...

  1. Usar un producto único para la instancia EntityManagerFactory, por unidad de persistencia.
  2. Crear un nuevo gestor de la entidad en cada llamada para recuperar uno, y no las comparta.

Uso de una enumeración para el mecanismo de singleton prevé ... ( A partir del Java Segunda edición )

  1. Ser concisa
  2. Proporciona la maquinaria serialización de forma gratuita
  3. Evita múltiple instanciación de EntityManagerFactory sin problemas de sincronización. Esto sucede porque los constructores enum son llamados en tiempo de carga de clases, y no puede ser llamado por su código.
  4. Asegura EntityManager no se comparte menos que un programador hace la elección correcta para hacerlo.
public enum PersistenceUnitFactory
{
    PERSISTENCE_UNIT_1("persistenceUnit1"),
    PERSISTENCE_UNIT_2("persistenceUnit2");

    private final EntityManagerFactory emf;
    /**
     * Maps the persistence unit name to this instance of the enum.
     *
     * @param persistenceUnitName the name of the peristence unit in
     *                            persistence.xml
     *
     * @see #getPersistenceUnitName()
     */
    PersistenceUnitFactory(final String persistenceUnitName)
    {
        emf = Persistence.createEntityManagerFactory(persistenceUnitName);
    }

    /**
     * Creates a new {@link EntityManager}.  NEVER share this across threads.
     * 
     * @return a new {@link EntityManager}
     */
    EntityManager createEntityManager()
    {
        return emf.createEntityManager();
    }
}

A continuación, es tan simple como pedir un EntityManager ...

PersistenceUnitFactory.PERSISTENCE_UNIT_1.createEntityManager();

Se puede añadir más unidades de persistencia medida que los necesite.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top