transaction example entitymanagerfactory ejemplo data spring hibernate jpa hibernate-entitymanager

example - Spring 3.1+Hibernate 4.1 JPA, fábrica de Entity Manager está registrada dos veces



spring data jpa hibernate (2)

Estoy usando Spring Framework 3.1 con Hibernate 4.1 como un proveedor de JPA, y tengo una configuración completamente funcional, pero cada vez que la aplicación web se inicia, veo este mensaje de advertencia:

14:28:12,725 WARN pool-2-thread-12 internal.EntityManagerFactoryRegistry:80 - HHH000436: Entity manager factory name (something) is already registered. If entity manager will be clustered or passivated, specify a unique value for property ''hibernate.ejb.entitymanager_factory_name''

La aplicación funciona bien, pero los mensajes de advertencia me molestan, y las horas de búsqueda, ajuste y experimentación no me han llevado a ninguna parte. Intenté cambiar el nombre de la fábrica y agregar y omitir fragmentos de configuración, todo en vano. Parece que algo en Spring o Hibernate solo está inicializando la fábrica del administrador de entidades dos veces.

FYI, estoy usando la funcionalidad de packagesToScan de LocalContainerEntityManagerFactoryBean para configurar el administrador de entidades sin un archivo persistence.xml.

Reduje mi XML de contexto de primavera a lo siguiente y el problema persiste:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.nightsword.driverClassName}"/> <property name="url" value="${jdbc.nightsword.url}"/> <property name="username" value="${jdbc.nightsword.username}"/> <property name="password" value="${jdbc.nightsword.password}"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="x.y"/> </bean> </beans>

Para completar, aquí está hibernate.properties:

hibernate.dialect=org.hibernate.dialect.MySQL5Dialect hibernate.ejb.entitymanager_factory_name=something

Y aquí está el resultado de registro de nivel de depuración extraído de org.springframework.orm y org.hibernate. Puede ver cómo a las 14: 40: 06,911 EntityManagerFactory se registra desde la primera vez, e inmediatamente después, LocalContainerEntityManagerFactoryBean parece comenzar desde el principio. Huh.

INFO: Deploying web application archive /opt/local/share/java/tomcat7/webapps/nightsword.war 14:40:06,149 INFO pool-2-thread-13 jpa.LocalContainerEntityManagerFactoryBean:264 - Building JPA container EntityManagerFactory for persistence unit ''default'' 14:40:06,219 DEBUG pool-2-thread-13 type.BasicTypeRegistry:143 - Adding type registration boolean -> org.hibernate.type.BooleanType@4cb91eff ... 14:40:06,882 DEBUG pool-2-thread-13 internal.SessionFactoryRegistry:62 - Initializing SessionFactoryRegistry : org.hibernate.internal.SessionFactoryRegistry@161bb7fe 14:40:06,882 DEBUG pool-2-thread-13 internal.SessionFactoryRegistry:75 - Registering SessionFactory: a3219dd8-7d59-45ac-9a5a-0d13e38dbb04 (<unnamed>) 14:40:06,882 DEBUG pool-2-thread-13 internal.SessionFactoryRegistry:82 - Not binding SessionFactory to JNDI, no JNDI name configured 14:40:06,882 DEBUG pool-2-thread-13 internal.SessionFactoryImpl:487 - Instantiated session factory 14:40:06,882 DEBUG pool-2-thread-13 internal.SessionFactoryImpl:1119 - Checking 0 named HQL queries 14:40:06,883 DEBUG pool-2-thread-13 internal.SessionFactoryImpl:1142 - Checking 0 named SQL queries 14:40:06,887 DEBUG pool-2-thread-13 internal.StatisticsInitiator:110 - Statistics initialized [enabled=false] 14:40:06,910 DEBUG pool-2-thread-13 internal.EntityManagerFactoryRegistry:56 - Initializing EntityManagerFactoryRegistry : org.hibernate.ejb.internal.EntityManagerFactoryRegistry@75cc9008 14:40:06,911 DEBUG pool-2-thread-13 internal.EntityManagerFactoryRegistry:66 - Registering EntityManagerFactory: something 14:40:06,967 INFO pool-2-thread-13 jpa.LocalContainerEntityManagerFactoryBean:264 - Building JPA container EntityManagerFactory for persistence unit ''default'' 14:40:06,967 DEBUG pool-2-thread-13 type.BasicTypeRegistry:143 - Adding type registration boolean -> org.hibernate.type.BooleanType@4cb91eff ... 14:40:07,128 DEBUG pool-2-thread-13 internal.SessionFactoryRegistry:75 - Registering SessionFactory: 81a9b5a6-83aa-46ee-be68-d642e6fda584 (<unnamed>) 14:40:07,128 DEBUG pool-2-thread-13 internal.SessionFactoryRegistry:82 - Not binding SessionFactory to JNDI, no JNDI name configured 14:40:07,129 DEBUG pool-2-thread-13 internal.SessionFactoryImpl:487 - Instantiated session factory 14:40:07,129 DEBUG pool-2-thread-13 internal.SessionFactoryImpl:1119 - Checking 0 named HQL queries 14:40:07,129 DEBUG pool-2-thread-13 internal.SessionFactoryImpl:1142 - Checking 0 named SQL queries 14:40:07,129 DEBUG pool-2-thread-13 internal.StatisticsInitiator:110 - Statistics initialized [enabled=false] 14:40:07,130 DEBUG pool-2-thread-13 internal.EntityManagerFactoryRegistry:66 - Registering EntityManagerFactory: something 14:40:07,130 WARN pool-2-thread-13 internal.EntityManagerFactoryRegistry:80 - HHH000436: Entity manager factory name (something) is already registered. If entity manager will be clustered or passivated, specify a unique value for property ''hibernate.ejb.entitymanager_factory_name''


¿Cómo está inicializando su contexto de aplicación Spring? ¿Estás usando Spring MVC?

A veces he visto configuraciones Spring MVC XML importando la otra aplicación. contexto XML, lo que provoca que dos veces algunos beans se declaren en el contexto de la aplicación y el contexto de la aplicación web.


Me encontré con el mismo problema pero en un escenario diferente. EntityManagerFactoryRegistry produce la misma advertencia HHH000436 cuando se ejecutan varias pruebas en la misma ejecución (es decir, la misma JVM) iniciada desde mi IDE.

El problema puede surgir en caso de que existan al menos dos clases de prueba que utilicen SpringJUnit4ClassRunner para cargar diferentes contextos de aplicación de prueba Spring cada uno de los cuales contenga una EntityManagerFactory .

La causa principal es que Hibernate mantiene un registro estático de EntityManagerFactory instancias de EntityManagerFactory , donde la creación de la segunda instancia puede causar la colisión de la que se trata el mensaje de registro. Entonces, ¿por qué no se da de baja la primera instancia después de que la primera prueba terminó de ejecutarse? Normalmente lo haría cuando el contexto de la aplicación que contiene esa instancia EntityManagerFactory se destruye. La razón por la que no ocurre durante la ejecución de la prueba es que el marco de trabajo de prueba de Spring almacena en caché todos los contextos cargados para evitar volver a cargar el mismo contexto exacto que necesitan las pruebas múltiples. Como resultado, los beans en estos contextos no se destruyen hasta que la última prueba haya terminado de ejecutarse, e Hibernate simplemente recopilará todas las instancias de EntityManagerFactory hayan creado.

Realmente no es un problema, pero si alguien está realmente molesto por el mensaje de advertencia, hay algunas maneras posibles de evitarlo:

  1. Asegúrese de que las instancias de EntityManagerFactory tengan un nombre diferente (están codificadas por nombre en el registro). EntityManagerFactoryImpl al constructor de EntityManagerFactoryImpl sobre cómo se deriva el nombre.
  2. Utilice @DirtiesContext en la clase de prueba para hacer que SpringJUnit4ClassRunner cierre el contexto y lo elimine de su caché de contexto inmediatamente después de ejecutar la clase de prueba.
  3. Simplemente configure el nivel de registro de EntityManagerFactoryRegistry en error ...

Espero que esto ayude a alguien.