[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