[ 
https://issues.apache.org/struts/browse/WW-1399?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_42823
 ] 

ahardy66 edited comment on WW-1399 at 12/23/07 10:29 AM:
-----------------------------------------------------------

Simplified my previous entry

The following is a servlet filter written for the most stripped-down, 
standards-compliant JPA implementation that I can currently reasonably put 
together. It's probably too specific to my requirements to be any use, but here 
it is anyway.

The DAOs retrieve the same entity manager every time by calling ContextManager. 
I don't use the Spring DAO component. Any call to 
EntityManagerFactory.createEntityManager() from the same thread will retrieve 
the same EntityManager - this is in the JPA spec. See section 5.2.

This is only for the extended persistence context paradigm - I haven't looked 
at implementing it in container with JEE transactions. 


public class OpenEntityManagerInViewFilter implements Filter
{
    public final void doFilter(ServletRequest request,
        ServletResponse response, FilterChain filterChain)
        throws ServletException, IOException
    {
        ContextManager.init();
        EntityManager entityManager = ContextManager.getEntityManager();

        try
        {
            filterChain.doFilter(request, response);
        }
        finally
        {
            ContextManager.closeEntityManager();
        }
    }

    public void destroy()
    {
    }

    public void init(FilterConfig newArg0) throws ServletException
    {
    }
}


public class ContextManager
{
    private static EntityManagerFactory entityManagerFactory;
    private static ThreadLocal<EntityManager> entityManagerThreadLocal =
        new ThreadLocal<EntityManager>();

    public static synchronized init() 
    {
        if (entityManagerFactory == null)
        {
            entityManagerFactory =
                Persistence.createEntityManagerFactory("myPersistenceUnit",
                    getJpaParameters());
        }
    }

    public static EntityManager getEntityManager()
    {
        EntityManager entityManager = entityManagerThreadLocal.get();
        if (entityManager == null)
        {
            entityManager = entityManagerFactory.createEntityManager();
            entityManagerThreadLocal.set(entityManager);
        }
        return entityManager;
    }


    public static void closeEntityManager()
    {
        EntityManager entityManager = entityManagerThreadLocal.get();
        if (entityManager != null && entityManager.isOpen())
        {
            entityManager.close();
        }
        // dump reference to EntityManager
        entityManagerThreadLocal.remove();
    }
}

NB For transaction management by the Spring Framework, the Spring context 
config sets up a transaction manager using 
org.springframework.orm.jpa.JpaTransactionManager which takes the 
EntityManagerFactory as a constructor parameter, using the ContextManager as 
the factory bean:

  <bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory">
      <bean class="org.permacode.ContextManager"
        factory-method="getEntityManagerFactory" />
    </property>
  </bean>

NB The method getJpaParameters() is superfluous if all the parameters are in 
the persistence.xml.

NB I stripped down this version here because the code as I have it in my app 
only initializes JPA on a just-in-time basis, i.e. if null, initialize. For 
this reason I have a lot of checks in the close-down methods to make it 
shutdown gracefully from any state.

      was (Author: ahardy66):
    Simplified my previous entry

The following is a servlet filter written for the most stripped-down, 
standards-compliant JPA implementation that I can currently reasonably put 
together. It's probably too specific to my requirements to be any use, but here 
it is anyway.

For transaction management by the Spring Framework, the Spring context config 
sets up a transaction manager using 
org.springframework.orm.jpa.JpaTransactionManager which takes the 
EntityManagerFactory as a constructor parameter.

The DAOs can retrieve the same entity manager that Spring is given. (I don't 
use the Spring DAO component.) Any call to 
EntityManagerFactory.createEntityManager() from the same thread will retrieve 
the same EntityManager - this is in the JPA spec. See section 5.2.

This is only for the extended persistence context paradigm - I haven't looked 
at implementing it in container with JEE transactions. 


public class OpenEntityManagerInViewFilter implements Filter
{
    public final void doFilter(ServletRequest request,
        ServletResponse response, FilterChain filterChain)
        throws ServletException, IOException
    {
        EntityManagerFactory entityManagerFactory =
            ContextManager.getEntityManagerFactory();
        EntityManager entityManager = ContextManager.getEntityManager();

        try
        {
            filterChain.doFilter(request, response);
        }
        finally
        {
            ContextManager.closeEntityManager();
        }
    }

    public void destroy()
    {
    }

    public void init(FilterConfig newArg0) throws ServletException
    {
    }
}


public class ContextManager
{
    private static ThreadLocal<EntityManager> entityManagerThreadLocal =
        new ThreadLocal<EntityManager>();

    public static EntityManager getEntityManager()
    {
        EntityManager entityManager = entityManagerThreadLocal.get();
        if (entityManager == null)
        {
            EntityManagerFactory entityManagerFactory =
                Persistence.createEntityManagerFactory("myPersistenceUnit",
                    getJpaParameters());
            entityManager = entityManagerFactory.createEntityManager();
            entityManagerThreadLocal.set(entityManager);
        }
        return entityManager;
    }

    public static void closeEntityManager()
    {
        EntityManager entityManager = entityManagerThreadLocal.get();
        if (entityManager != null && entityManager.isOpen())
        {
            entityManager.close();
        }
        // dump reference to EntityManager
        entityManagerThreadLocal.remove();
    }
}

  
> MailReader - Migrate to JPA and Derby
> -------------------------------------
>
>                 Key: WW-1399
>                 URL: https://issues.apache.org/struts/browse/WW-1399
>             Project: Struts 2
>          Issue Type: Improvement
>          Components: Example Applications
>            Reporter: Ted Husted
>            Assignee: Ted Husted
>            Priority: Minor
>             Fix For: 2.1.x
>
>
> The in-memory XML database used by the MailReader is interesting, but a 
> best-practices example that used the JPA and a SQL DBMS would be more 
> instructive. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to