How to get entitymanager programmatically in Spring?

user1595858 picture user1595858 · Sep 7, 2013 · Viewed 13.6k times · Source

I am trying to integrate our DAO maven module to spring, we don't want to change any code of the dao. Previously, all the dao classes get entity manager using the following way.

Persistence.getEntityManager()

In spring I see lot of example using annotation to inject the entity manager but that need change in dao code. Is there a way I can modify the below class to make it work in spring?

 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();
        }
    }

Spring Configuration

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

Answer

user1595858 picture user1595858 · Sep 9, 2013

I found the solution, see below

Updated

    @Repository
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";

    private static EntityManagerFactory emf;

    @PersistenceUnit(unitName=PERSISTENCE_UNIT_EMYED)
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        PersistenceManager.emf = emf;
    }
    /**
     * 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 emf.createEntityManager();
    }
}