2012-02-21 28 views
5

No estoy usando Spring, así que estoy creando una instancia de EntityManager dentro de una clase.Hibernate EntityManager, ¿se supone que debe usarse como singleton?

Usé ingeniería inversa Hibernate-Eclipse para generar automáticamente las clases. Todas estas clases tienen una instancia de EntityManager.

No estoy 100% seguro de cómo funciona Hibernate con EntityManager, así que me pregunto si está bien que se realicen tantas instancias de esta clase (EntityManager), por ejemplo, ¿habrá problemas con las transacciones?

¿Debo simplemente hacer una clase separada que distribuya una instancia estática de un EntityManager para todas mis otras clases? ¿O no importa?

EDIT: Veo que hay algo llamado @PersistenceContext, no parece cargar mi persistence.xml como un bean en la variable de instancia, ¿esta característica requiere la primavera? (Me da excepción de puntero nulo, porque nunca se inyectó)

recorte de código desde donde intento utilizar @PersistenceContext

@PersistenceContext(unitName = "manager1") 
private EntityManager entityManager; 

mi persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
      version="2.0"> 
    <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 

     <properties> 

     <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> 
     <property name="javax.persistence.jdbc.user" value="root"/> 
     <property name="javax.persistence.jdbc.password" value="mypassword"/> 
     <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/ptbrowserdb"/> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> 
     </properties> 
    </persistence-unit> 
</persistence> 
+0

¿Puedes simplemente eliminar el modificador de acceso privado (en 'EntityManager') y probar? – Santosh

Respuesta

10

Ver este artículo: JPA Architecture lo explica muy bien.

En general, necesita un solo administrador de entidad por transacción. Y este Administrador de Entidades no debe usarse en dos transacciones al mismo tiempo.

Clairificación: Es decir, no uso un solo administrador de entidad para diferentes unidades de trabajo. Típico de una transacción en una unidad de trabajo, si usted tiene diferentes transacciones de una unidad de trabajo, entonces se puede utilizar la misma entidad gestora

Si utiliza primavera continuación Primavera hacer esto manipulación para usted si utiliza la anotación @PersistenceContext para inyectar el EntityManager. Por defecto, Spring "vincula" el EntityManager inyectado (a través de un proxy) a la transacción actual. (Y la transacción está "vinculada" al hilo).

@See Spring Reference 13.5.2 Implementing DAOs based on plain JPA - contiene un párrafo interesante después de los ejemplos del código.

+0

jaja, no necesita un único administrador de entidades por transacción. Un administrador de entidades representa una sesión abierta (conexión) a la base de datos, es muy costoso usarlo solo para una transacción. ¡1 sesión por operación se considera un antipatrón! https://developer.jboss.org/wiki/Sessionsandtransactions – Maurice

+0

@Maurice: este es un artículo interesante, pero trata sobre el "viejo" modelo de Session/SessionFactory de Hibernate, pero esta pregunta es sobre JPA. Por lo que sé, sé esto en uno de los pocos temas en los que JPA e Hibernate-Session son diferentes. Eche un vistazo al capítulo "5.1 Entidad gestor y ámbitos de transacción" en https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/transactions.html - afirma: "Un EntityManager es una solución económica , un objeto que no se puede enhebrar y que se debe usar una vez, para un solo proceso comercial, una sola unidad de trabajo y luego se descarta ". – Ralph

+0

y un único proceso comercial puede consistir en múltiples transacciones, ¿verdad? ¿O no estás de acuerdo? ¿No dicen en mi enlace que supongo que debe poner más de una transacción en una sesión, de lo contrario sería un antipatrón? – Maurice

1

Es necesario una dependencia Marco de inyección como Spring o Google Guice para inyectar objetos en su clase, de lo contrario no se inyectará automáticamente.

Básicamente esta es una anotación proporcionada por JPA que funcionará en conjunto con Hibernate o cualquier otro marco ORM por decir pero necesita un marco DI para inyectar los objetos.

En cuanto a la instancia única del administrador de entidades, no creo que lo necesite si pasa Spring, ya que se encarga de administrar las instancias y las transacciones vinculando su entidad manager con la transacción jpa.

+1

En J2EE no necesita ningún marco de inyección de dependencia externo. Las inyecciones son manejadas por el contenedor. – Santosh

+0

No necesita un marco de Inyección de Dependencia: puede hacerlo usted mismo: en una aplicación web, por ejemplo, con una banda de rodadura local con el administrador de entidad y un EntityManagerPerRequestPatternFilter – Ralph

+0

@Ralph - Sí, podemos hacer la inyección nosotros mismos, pero para evitar los gastos generales, hemos probado marcos para DI ... spring o guice lo haremos sin problemas ... siempre que estos sean parte de la pila de aplicaciones ... – raddykrish

Cuestiones relacionadas