4

DAO Maven モジュールを Spring に統合しようとしていますが、dao のコードを変更したくありません。以前は、すべての dao クラスが次の方法を使用してエンティティ マネージャーを取得していました。

Persistence.getEntityManager()

春には、アノテーションを使用してエンティティマネージャーを挿入する例がたくさんありますが、dao コードを変更する必要があります。以下のクラスを変更して春に動作させる方法はありますか?

 public class PersistenceManager
    {

        /**
         * Key that stores the entity manager.
         */
        private static final String ENTITY_MANAGER_INSTANCE = "ENTITY_MANAGER_INSTANCE";
        /**
         * Persistence unit for eMyEd
         */
        private static final String PERSISTENCE_UNIT_EMYED = "application_openjpa";
        /**
         * The static factory used across the JVM
         */
        private static final EntityManagerFactory ENTITY_MANAGER_FACTORY = Persistence
                .createEntityManagerFactory(PERSISTENCE_UNIT_EMYED);

        /**
         * Cleanup any entity managers created in the thread context.
         */
        public static void close()
        {
            EntityManager emInstance = getEntityManager();
            try
            {
                if (emInstance.isOpen())
                {
                    emInstance.close();
                }
            }
            catch (Throwable t)
            {
                // ignore
            }
            finally
            {
                ThreadContext.instance.clear();
            }
        }

        /**
         * Returns the Entity manager associated with the given thread context. If
         * none available, one is created and set on the thread context and the same
         * is returned.
         *
         * @return
         */
        public static EntityManager getEntityManager()
        {
            EntityManager emInstance = (EntityManager) ThreadContext.instance
                    .get(ENTITY_MANAGER_INSTANCE);
            if (emInstance == null)
            {
                emInstance = createEntityManager();
                emInstance.setFlushMode(FlushModeType.COMMIT);
                ThreadContext.instance.put(ENTITY_MANAGER_INSTANCE, emInstance);
            }
            try
            {
                // try to join the current active transaction
                emInstance.joinTransaction();
            }
            catch (TransactionRequiredException notSupportedEx)
            {
                // If there was no transaction to join. Ignore
            }
            catch (Throwable unknownEx)
            {
                // If there was no transaction to join. Ignore
            }
            return emInstance;

        }

        /**
         * Create a new entity manager.
         *
         * @return
         */
        private static EntityManager createEntityManager()
        {
            return ENTITY_MANAGER_FACTORY.createEntityManager();
        }
    }

春の構成

<description>Example configuration to get you started.</description>
    <context:component-scan base-package="com.veera" />
 <!-- tell Spring that it should act on any @PersistenceContext and @Transactional annotations found in bean classes -->
    <tx:annotation-driven transaction-manager="transactionManager" />
    <!-- ******************************************************************** -->
    <!-- Setup the transaction manager -->
    <!-- ******************************************************************** -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>


    <!-- ******************************************************************** -->
    <!-- Setup each data source -->
    <!-- ******************************************************************** -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </bean>

    <!-- ******************************************************************** -->
    <!-- Setup each persistence unit -->
    <!-- ******************************************************************** -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
                <property name="databasePlatform"
                    value="org.apache.openjpa.jdbc.sql.MySQLDictionary" />
            </bean>
        </property>
        <property name="persistenceUnitName" value="application_openjpa" />
        <!--  property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property -->
        <!-- property name="jpaProperties"> <props> <prop key="hibernate.hbm2ddl.auto">create-drop</prop> 
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> 
            </props> </property -->
    </bean>
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

Persistence.xml

    <persistence-unit name="application_openjpa"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>com.veera.jpa.Item</class>
        <class>com.veera.jpa.Order</class>
        <class>com.zreflect.emyed.entity.user.User</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <!--  property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema" /
            <property name="openjpa.InitializeEagerly" value="true"/-->
            <property name="openjpa.Log" value="File=stdout, DefaultLevel=INFO, Runtime=INFO, SQL=TRACE"/>
        </properties>
    </persistence-unit>

</persistence>
4

2 に答える 2

1

EntityManager定義上スレッドセーフではないため、唯一の (まだ醜い) 解決策は、 をEntityManagerFactory静的に保持し、EntityManager要求に応じてファクトリからインスタンスを作成することです。

このアプローチでは、依存性注入の原因を使用するように DAO を変更することをお勧めします。JPA インフラストラクチャ全体をブートストラップしないと、DAO は本質的にユニットテストできなくなります。

于 2013-09-11T03:43:25.193 に答える