My scenario is that I don't want to do my entity manager interaction in a session bean
- I want to use a layering approach that has Session beans <-> Business Delegates
<-> DAOs <-> JPA entities.
I'm getting frustrated that I cannot inject an entity manager into a DAO class inside
the ejb container becasue it is not an EJB. I could use a jndi lookup, but then I jhave to
worry about closing the entity manager.
What I really want is to be able to access the EntityManager that was injected into the
session bean that was my entry point to the container, but
I do not want to pollute my BD and DAO API's with entity manager parameters.
So, can I use ThreadLocal's? Do the folk at JBoss have a paradigm for doing this, or
am I doing something completely stupid?
The example code that follows is significantly trimmed. I've also left out the BD, and
ignore the fact that a JPA entity is being returned to the client.
I have a session bean with a simple getter method to load an entity. It delegates to a
DAO
| @Stateful
| @Remote
| public class StatefulColumnGroupServiceBean {
|
| @PersistenceContext(unitName="MyApp",
type=PersistenceContextType.EXTENDED)
| protected EntityManager em;
|
| public ColumnGroupEntity getColumnGroup(int iThreadNumber, long id) throws
ServerException {
| EntityManagerResource.getInstance().set(em);
| ColumnGroupEntity cgvo = null;
| try {
| cgvo = ColumnGroupDAO.getInstance().getColumnGroup(id);
| }
| catch (DAOException e) {
| log.error(e);
| throw new ServerException(
MessageFactory.getMessage("Bean.CannotFind", "ColumnGroup") + id, e );
| }
| return cgvo;
| }
| }
|
The DAO is
| public class ColumnGroupDAO {
|
| public ColumnGroupEntity getColumnGroup( long id ) throws DAOException {
| EntityManager em = EntityManagerResource.getInstance().get();
|
| ColumnGroupEntity res = null;
| try {
| res = em.find(ColumnGroupEntity.class, id);
| }
| catch (RuntimeException e) {
| throw new DAOException(MessageFactory.getMessage("DAO.FindError",
getClass().getName()) + id, e);
| }
| return res;
| }
|
|
| protected ColumnGroupDAO() {
| }
|
| public static ColumnGroupDAO getInstance() {
| if( instance == null ) {
| synchronized( ColumnGroupDAO.class ) {
| if( instance == null ) {
| instance = new ColumnGroupDAO();
| }
| }
| }
| return instance;
| }
|
| private static ColumnGroupDAO instance = null;
|
| }
|
and the EntityManager is passed between bean and DAO by using a singleton ThreadLocal
wrapping an EntityManager instance
| public class EntityManagerResource extends ThreadLocalResource<EntityManager> {
|
| private static EntityManagerResource instance = null;
|
| public static EntityManagerResource getInstance( ) {
| if( instance == null ) {
| synchronized( EntityManagerResource.class ) {
| if( instance == null ) {
| instance = new EntityManagerResource( );
| }
| }
| }
| return instance;
| }
|
| protected EntityManagerResource() {
| }
| }
|
| public abstract class ThreadLocalResource<T> {
|
| private final ThreadLocal<T> resource = new ThreadLocal( );
|
| public void set( T em ) {
| resource.set(em);
| }
|
| public T get( ) {
| return resource.get();
| }
| }
|
|
Does this make sense? Any suggestions?
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3984556#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...