You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Adam Hardy (JIRA)" <ji...@apache.org> on 2007/12/18 00:20:35 UTC
[jira] Commented: (WW-1399) MailReader - Migrate to JPA and Derby
[ https://issues.apache.org/struts/browse/WW-1399?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_42823 ]
Adam Hardy commented on WW-1399:
--------------------------------
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.
As you can see, it feeds an entity manager into the Spring Framework use in transaction management, and it is managed by the org.permacode.ContextManager, from which the DAOs can retrieve the same entity manager that Spring is given. (I don't use the Spring DAO component.)
Fortunately part of the JPA spec says that the EntityManagerFactory must serve up the same entity manager to any calls made by the same thread (5.2).
This is only for the extended persistence context paradigm - I haven't looked at implementing it in container with JEE transactions.
package org.permacode.web;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.permacode.ContextManager;
import org.permacode.PermacodeException;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
public class OpenEntityManagerInViewFilter implements Filter
{
/**
* Binds the JPA EntityManager for the thread into the Spring Framework's
* (@link
* org.springframework.transaction.support.TransactionSynchronizationManager)
* for use by the Spring Frameworks non-standardised Transaction Management,
* using the EntityManagerFactory as the key.
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public final void doFilter(ServletRequest request,
ServletResponse response, FilterChain filterChain)
throws ServletException, IOException
{
EntityManagerFactory entityManagerFactory =
ContextManager.getEntityManagerFactory();
try
{
EntityManager entityManager = ContextManager.getEntityManager();
TransactionSynchronizationManager.bindResource(
entityManagerFactory, new EntityManagerHolder(entityManager));
}
catch (PersistenceException ex)
{
throw new PermacodeException("Could not create JPA EntityManager",
ex);
}
try
{
filterChain.doFilter(request, response);
}
finally
{
TransactionSynchronizationManager
.unbindResource(entityManagerFactory);
ContextManager.closeEntityManager();
}
}
public void destroy()
{
}
public void init(FilterConfig newArg0) throws ServletException
{
}
}
In attempt to make this more useful, I thought I should include the relevant ContextManager methods as pseudo-code (it was a bit more complex actually):
public static EntityManager getEntityManager()
{
EntityManager entityManager = threadLocalEntityManager.get();
if (entityManager == null)
{
entityManagerFactory =
Persistence.createEntityManagerFactory(persistenceUnitName,
getJpaParameters());
entityManager = getEntityManagerFactory().createEntityManager();
threadLocalEntityManager.set(entityManager);
}
return entityManager;
}
public static void closeEntityManager()
{
EntityManager entityManager = threadLocalEntityManager.get();
if (entityManager != null && entityManager.isOpen())
{
EntityTransaction dbTransaction = entityManager.getTransaction();
if (dbTransaction != null && dbTransaction.isActive())
{
logger.debug("rolling back transaction - "
+ "should be closed at this point normally");
dbTransaction.rollback();
}
logger.debug("closing entity manager");
entityManager.close();
}
else
{
logger.warn("EntityManager closed already.");
}
// dump reference to EntityManager
threadLocalEntityManager.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.