[jboss-user] [EJB 3.0] - EntityManagers and DAOs

chrismeadows do-not-reply at jboss.com
Thu Nov 9 10:40:02 EST 2006


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

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3984556



More information about the jboss-user mailing list