4 Replies Latest reply on Jan 10, 2008 9:23 PM by di pas

    Correct use of DAO with seam managed-persistence-context

    di pas Newbie

      In your excellent book Java Persistence with Hibernate starting from page 727 (i have studied the entire book) you wrote about how to write DAO's with EJBs. There you suggest to define the DAOs as SLSB with @TransactionAttribute(REQUIRED). In the GenericEJB3DAO the EntityManager is injected with @PersistenceContext from the container and in the SFSB the EntityManager is also injected with @PersistenceContext, additionaly you defined an Extended PersistenceContext with FlushMode.MANUAL. The DAO's are injected by @EJB into the SFSB.


      Im my understanding, from now on, all methods in the SFSB are Transactional and the EntityManager will never write to the Database without explicit call to em.flush().


      In the Seam Reference and the wiki example I found an other solution witch works with Seam manged-persistence-context defined in context.xml.


      I tried this setup - it looks as follows:


      Transaction Management in persistence.xml


      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/obasDevDatasource</jta-data-source>
      
      ...
      <properties>
      <property name="jboss.entity.manager.factory.jndi.name" value="java:/obasEntityManagerFactory"/>
      <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" />
      </properties>
      



      components.xml


      <persistence:managed-persistence-context
                  name="entityManager"
                  auto-create="true"
                  persistence-unit-jndi-name="java:/obasEntityManagerFactory"/>
      



      in the GenericDAO the EM is injected with @IN


      public abstract class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> {
      
          private Class<T> persistentClass;
      
          @In
          private EntityManager entityManager;
      



      the concrete implementation looks like this (no explicit scope defined!)


      @Name("serviceCompDAO")
      @AutoCreate
      @Transactional
      public class ServiceCompDAOImpl extends GenericDAOImpl<ServiceComp, Long> implements ServiceCompDAO, Serializable {
      }
      



      and this is the SFSB


      @Stateful
      @Name("serviceCompAdmin")
      @Scope(org.jboss.seam.ScopeType.CONVERSATION)
      public class ServiceCompAdminAction implements ServiceCompAdmin, Serializable {
          @In
          private ServiceCompDAO serviceCompDAO;
      ...
          // all methods with DAO access are defined as Transactional
          @Restrict("#{s:hasPermission('serviceCompAdmin','edit', serviceCompAdmin.serviceComp)}")
          @Transactional
          public void storeData() {
      ...
              serviceComp = serviceCompDAO.store(serviceComp);
              serviceCompDAO.flush();
      ...
      }
      }
      



      If I now add/remove associations to/from the Master Object I need to define...

      @Begin(join = true, flushMode = FlushModeType.MANUAL)


      Otherwise the EM is flushing to the Database - even without calling the DAO but only by adding objects to the collection of the Master Object - at the end of the method. It seems not possible to define the flushMode once for the entire conversation. I tried do define the FlushMode in pages.xml with 
      <begin-conversation flush-mode="MANUAL" />

      but the flushMode was not propagated to all the methods of the SFSB or to the DAO.


      The pageflow - witch is involved in this conversation - is started by this link


      <s:link view="/view/core/security/serviceCompList.xhtml" pageflow="serviceCompAdmin" propagation="begin">
      



      Now my questions are:


      Is my implementation correct and I need to define the flushMode on each collection-managment-method - or would it be better to change to some other setup?


      How can I define the flushMode for the entire conversation?


      What is the best Scope for the DAOs?