2 Replies Latest reply on Oct 10, 2008 4:08 PM by Leandro Hermida

    Generic DAO pattern with Seam-managed transactions and SMPC doesn't work

    Leandro Hermida Newbie

      Hi,


      In my previous post (here) where I didn't get any responses I was getting the following error:



      Error performing 'org.sysfusion.core.session.RegisterAction.register()' --> javax.ejb.EJBTransactionRolledbackException: javax.persistence.TransactionRequiredException: no transaction is in progress

      after submitting a simple registration form backed by a SLSB.  After much troubleshooting I have found what might be the cause which is really strange: if you inject and use in the session bean a Seam component EJB 3.0 DAO layer with Seam-managed transactions and SMPC then transactions don't get started and you get the above error. If I inject the entityManager directly into the session bean and use it instead of the DAO layer then everything works fine... weird, especially since the DAO layer has inside of it the injected entityManager.


      In my project I implement a Generic DAO pattern and layer exactly as shown in Java Persistence with Hibernate except that my implementation uses SMPC.  The code is like this:


      GenericDAO.java


      public interface GenericDAO<T, ID extends Serializable> {
          // common method interfaces (CRUD, loads, common finds)
      }



      GenericDAOSeamJPAImpl.java


      public abstract class GenericDAOSeamJPAImpl<T, ID extends Serializable>
              implements GenericDAO<T, ID> {
      
          private Class<T> entityClass;
          
          @In
          protected EntityManager entityManager;
          
          // common method implementations (CRUD, loads, common finds using entityManager)
      }



      Then here's one of the entity implementations:


      UserDAO.java


      @Local
      public interface UserDAO extends GenericDAO<User, Long> {
          // User-specific method interfaces
      }



      UserDAOSeamJPAImpl.java


      @Stateless
      @Name("userDAO")
      @AutoCreate
      public class UserDAOSeamJPAImpl extends GenericDAOSeamJPAImpl<User, Long>
              implements UserDAO {
          // User-specific method implementations (using entityManager)
      }



      Now in the JSF or other session beans you would do:


      RegisterActionImpl.java


      @Stateless
      @Name("registerAction")
      @Scope(ScopeType.PAGE)
      public class RegisterActionImpl implements RegisterAction {
      
          @In
          private UserDAO userDAO;
          
          public String register() {
              // business logic here using userDAO fails with no transaction error!!
          }
      }



      If I ignore my DAO layer and replace the code to look like this:


      @Stateless
      @Name("registerAction")
      @Scope(ScopeType.PAGE)
      public class RegisterActionImpl implements RegisterAction {
      
          @In
          private EntityManager entityManager;
          
          public String register() {
              // business logic here using entityManager directly works...
          }
      }



      What am I doing wrong?  Am I misunderstanding how to implement an Seam component EJB 3.0 DAO layer with Seam-managed transactions and SMPC?


      any help would be very appreciated,


      leandro