10

Spring Framework3.1とHibernate4.1をJPAプロバイダーとして使用しており、完全に機能するように設定されていますが、Webアプリを起動するたびに次の警告メッセージが表示されます。

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'

アプリケーションは問題なく機能しますが、そのような警告メッセージは私を悩ませ、何時間もの検索と調整と実験は私をどこにも導きませんでした。工場名を変更し、構成のチャンクを追加および省略してみましたが、まったく役に立ちませんでした。SpringまたはHibernateの何かが、エンティティマネージャーファクトリを2回初期化しているようです。

参考までに、LocalContainerEntityManagerFactoryBeanのpackagesToScan機能を使用して、persistence.xmlファイルなしでエンティティマネージャーを構成しています。

SpringコンテキストのXMLを次のように整理しましたが、問題は解決しません。

<?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>

完全を期すために、ここにhibernate.propertiesがあります。

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

そして、org.springframework.ormとorg.hibernateの両方からの抜粋されたデバッグレベルのログ出力です。14:40:06,911に、EntityManagerFactoryが最初から登録され、その直後にLocalContainerEntityManagerFactoryBeanが最初から最初からやり直しになっていることがわかります。は。

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'
4

2 に答える 2

13

同じ問題に遭遇しましたが、別のシナリオで発生しました。IDE から開始された同じ実行 (つまり、同じ JVM) で複数のテストを実行すると、同じ警告がEntityManagerFactoryRegistry生成されます。HHH000436

を使用して少なくとも 2 つのテストクラスが存在し、それぞれが.SpringJUnit4ClassRunnerEntityManagerFactory

根本的な原因は、Hibernate がインスタンスの静的レジストリを維持していることEntityManagerFactoryです。2 番目のインスタンスの作成により、ログ メッセージで説明されている衝突が発生する可能性があります。では、最初のテストの実行が終了した後、最初のインスタンスが登録解除されないのはなぜでしょうか? 通常は、そのEntityManagerFactoryインスタンスを含むアプリ コンテキストが破棄されたときに発生します。テスト実行中に発生しない理由は、Spring テスト コンテキスト フレームワークが、ロードされたすべてのコンテキストをキャッシュして、複数のテストで必要になる可能性があるまったく同じコンテキストを再ロードすることを避けるためです。その結果、これらのコンテキストの Bean は、最後のテストの実行が完了するまで破棄されず、Hibernate はEntityManagerFactoryこれまでに作成されたすべてのインスタンスを収集するだけです。

これは実際には問題ではありませんが、誰かが警告メッセージに本当に悩まされている場合は、警告メッセージを表示しないようにする方法がいくつかあります:

  1. インスタンスに別の名前が付けられていることを確認してくださいEntityManagerFactory(レジストリで名前がキーになっています)。EntityManagerFactoryImpl名前の由来のコンストラクターを確認してください。
  2. @DirtiesContextテスト クラスで使用してSpringJUnit4ClassRunner、 がコンテキストを閉じ、テスト クラスの実行直後にコンテキスト キャッシュから削除します。
  3. ログレベルEntityManagerFactoryRegistryをエラーに設定するだけです...

これが誰かに役立つことを願っています。

于 2013-02-24T13:40:32.477 に答える
10

Spring Application Context をどのように初期化していますか? Spring MVC を使用していますか?

Spring MVC XML 構成が他のアプリをインポートしているのを見たことがあります。一部の Bean はアプリケーション コンテキストと Web アプリケーション コンテキストで宣言されているため、2 回インスタンス化されます。

于 2012-06-06T09:28:14.230 に答える