69 votos

La Inyección De EntityManager Vs. EntityManagerFactory

Una pregunta larga, por favor tengan paciencia conmigo.

Estamos utilizando Spring+JPA para una aplicación web. Mi equipo está debatiendo sobre la inyección EntityManagerFactory de la GenericDAO (un DAO basado en los Genéricos algo en las líneas proporcionadas por APPFUSE, no usamos JpaDaosupport por alguna razón) a través de la inyección EntityManager. Estamos utilizando la aplicación "persistencia gestionada".

Los argumentos en contra de la inyección de un EntityManagerFactory es que es muy pesado y por lo tanto no es necesario, el EntityManager no lo necesitamos. También, a medida que la Primavera iba a crear una nueva instancia de un DAO para cada petición web(dudo que esto) no va a haber problemas de concurrencia que en el mismo EntityManager ejemplo es compartida por dos hilos.

El argumento para la inyección de EFM es que es una buena práctica a lo largo de todo siempre es bueno tener un identificador para una fábrica.

No estoy seguro de cual es el mejor método, por favor alguien puede aclararme?

50voto

skaffman Puntos 197885

Los pros y contras de inyectarse EntityManagerFactory vs EntityManager son todos los enunciados en la Primavera docs aquí, no estoy seguro de si puedo mejorar en eso.

Diciendo eso, hay algunos puntos en su pregunta que debe ser aclarado.

...La primavera para crear una nueva instancia de un DAO para cada petición web...

Esto no es correcto. Si el DAO es un Manantial de frijol, entonces es un singleton, a menos que se configure de otra forma a través de la scope atributo del bean definición. Crear una instancia de un DAO para cada solicitud sería una locura.

El argumento para la inyección de EFM es que es una buena práctica a lo largo de toda su siempre es bueno tener un identificador para un de fábrica.

Este argumento no retienen el agua. En General una buena práctica dice que un objeto debe ser inyectado con el mínimo de colaboradores que necesita para hacer su trabajo.

26voto

SB. Puntos 702

Me estoy poniendo lo que finalmente han reunido...

Aunque EntityManagerFactory instancias sean seguros para subprocesos, EntityManager de los casos, no. La inyección de JPA EntityManager se comporta como un EntityManager que se recuperan de una aplicación de servidor JNDI de medio ambiente, como los definidos por la especificación JPA. Que los delegados de todas las llamadas a la corriente transaccional EntityManager, si los hubiere; en caso contrario, se cae de vuelta para una nueva EntityManager por operación, en efecto haciendo que su uso es seguro para subprocesos. -- A Partir De La Primavera De Referencia

Esto significa que, por JPA especificaciones EntityManager instancias no son seguros para subprocesos, pero si la Primavera maneja, lo que se hizo seguro para Subprocesos.


Si usted está utilizando la Primavera, es mejor inyectar EntityManagers en lugar de EntityManagerFactory.


9voto

James McMahon Puntos 14356

Creo que esto ya ha sido cubierto, pero sólo para reforzar algunos puntos.

  • El DAO, si se inyecta en la Primavera, es un singleton por defecto. Usted tiene que explícitamente establece el ámbito en el prototipo para crear una nueva instancia cada vez.

  • La entidad pesebre inyectado por @PersistenceContext es seguro para subprocesos.

Dicho esto, yo tenía algunos problemas con un singleton DAO en mi aplicación multiproceso. Terminé haciendo el DAO una partida de frijol y que se solucionó el problema. Así, mientras que la documentación puede decir una cosa, probablemente te interese probar la aplicación a fondo.

Seguimiento:

Creo que parte de mi problema es que estoy usando

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

Si utiliza PersistenceContextType.EXTENDIDO, tenga en cuenta que usted tiene que, si he entendido bien, cerrar manualmente la transacción. Ver este hilo para obtener más información.

Otro de Seguimiento:

El uso de una partida de DAO es una muy mala idea. Cada instancia de la DAO tendrá su propia persistencia de la memoria caché y los cambios de una caché de no ser reconocido por otros daos. Lo siento por el mal consejo.

6voto

Gaël Marziou Puntos 914

He encontrado que la configuración de la @Repositorio de Primavera anotación en nuestro DAOs y tener EntityManager administrado por la Primavera y se inyecta por @PersistenceContext anotación es la forma más conveniente para conseguir que todo funcione con fluidez. Usted se beneficia de la seguridad de los subprocesos de la compartida EntityManager y a excepción de la traducción. De forma predeterminada, el compartido EntityManager se encargará de gestionar las transacciones si se combinan varios DAOs de un administrador, por ejemplo. Al final te encontrarás con que tu DAOs se vuelven anémicos.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X