4 Replies Latest reply on Jun 12, 2009 6:11 PM by Arbi Sookazian

    using two parallel nested conversations with parent atomic conversation

    Arbi Sookazian Master

      I have a use case which has a dataTable/form on main page and two links to show modalPanels with forms in the same page.  All three forms are editable for update tx's.


      I typically use SMPC with Hibernate MANUAL flush for write-behind, etc.  The advantage of doing this in a situation where user can only update data in a form is that you don't have to write one line of HQL/JPAQL, etc. to persist the data (em.flush() is all you need before the tx commits!). 


      I want to be able to implement/model isolated atomic conversations for all three cases such that when I call em.flush(), the PersistenceContext dirty data is not flushed for the main/parent LRC but is flushed/synchronized with db for the nested conversations.


      Is it possible to do this isolation with atomic conversations with Seam and what is the best way to solve this?  thx.

        • 1. Re: using two parallel nested conversations with parent atomic conversation
          Arbi Sookazian Master

          Well it looks like either you can't do what I'd like to do or my implementation is wrong.


          AFAIK, the EntityManager/PersistenceContext in JPA serves as a 1st level cache (as does Session interface in Hibernate).  But it keeps track of changes to all persistent/managed (i.e. not transient or detached) entities.


          So in my case, even though I'm ending a nested conversation for the modalPanel/form submission and flushing the SMPC, I'm unable to achieve the isolation that I'm needing (i.e. when I enter a different value in a cell in formA and enter a different value in formB and flush(), both entities are flushed and thus there are 2 update tx's that are committed to the db.)


          So what should I do now?  Not use MANUAL flush and write entityManager.merge() statements on the required entities in the appropriate save action methods?

          • 2. Re: using two parallel nested conversations with parent atomic conversation
            Arbi Sookazian Master

            now I turned off MANUAL flush (so it's AUTO).


            seems that with AUTO, the PersistenceContext is flushed whenever a tx commits.  I noticed that when I added this annotation to a business method, the persitence (prematur update to main form) did not occur:


            @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                 public void populateListValueParam(Integer rowIndex){
                      populateListValueParamList = entityManager.createQuery("select lvp from ListValueParam lvp where lvp.listValue.listValueId = :listValueId")
                                                                                  .setParameter("listValueId", listValueList.get(rowIndex).getListValueId())
                                                                                  .getResultList();
                 }



            So how are you supposed to handle a use case like this?  Break it into three pages?  Is there not a way to handle the persistence/tx's properly with one JSF and two embedded forms/modalPanels?

            • 3. Re: using two parallel nested conversations with parent atomic conversation
              Arbi Sookazian Master

              Ok, this is the current implementation/design:


              1 JSF/facelet (main form plus two modalPanel forms)


              1 conversation-scoped SFSB


              The (as yet untested) solution to this problem is to use one SFSB for each form.


              This way there will be three independent/isolated EntityManager instances injected by @In (SMPC) or possibly @PersistenceContext if required.  Obviously it's better to use extended type rather than tx-scoped PC if lazy-loading is a possibility (prevent detachment of entities and thus LazyInitializationException with extended type).


              As a result, nested conversations is not required for this use case.  The mini-use cases are independent so they need their own LRCs.


              So now I'm hoping to achieve atomic conversations for each form (mini-use case), or...


              application transaction, a special type of transaction that allows modifications
              made to managed entities to be queued across requests until the end of
              the use case, at which time the changes are committed to the database within a database
              transaction.



              The key here is ensuring a distinct LRC for each SFSB (mini-use case or form) b/c SMPC remains available as long as the conversation is active, regardless of which components come and go.  <-- DAllen SiA

              • 4. Re: using two parallel nested conversations with parent atomic conversation
                Arbi Sookazian Master

                The current solution for this scenario (which is working well thus far) is to use two SMPCs.  One for the main form and the other for the support forms in any of the modalPanels in the same JSF page.


                components.xml:


                <persistence:managed-persistence-context name="entityManager"
                                                     auto-create="true"
                                      persistence-unit-jndi-name="java:/boBETSEntityManagerFactory"/>    
                   
                   <!-- using entityManager2 for ListValueParamAction for now! trying to isolate the em.flush() such that we can achieve atomic conversations for the
                   base form as well as the popup form! -->                   
                   <persistence:managed-persistence-context name="entityManager2"
                                                     auto-create="true"
                                      persistence-unit-jndi-name="java:/boBETS2EntityManagerFactory"/> 



                persistence.xml:


                   <persistence-unit name="boBETS">
                      <provider>org.hibernate.ejb.HibernatePersistence</provider>
                      <jta-data-source>java:/boBETSDatasource</jta-data-source>
                      <properties>
                         <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
                         <!-- <property name="hibernate.hbm2ddl.auto" value="validate"/>   -->
                         <property name="hibernate.show_sql" value="true"/>
                         <property name="hibernate.format_sql" value="true"/>
                         <property name="hibernate.generate_statistics" value="true"/>
                         <property name="jboss.entity.manager.factory.jndi.name" value="java:/boBETSEntityManagerFactory"/>
                         <property name="hibernate.default_catalog" value="boBETS"/>
                         <property name="hibernate.default_schema" value="dbo"/>
                      </properties>
                   </persistence-unit>
                   
                   <!-- using boBETS2 for ListValueParamAction for now! trying to isolate the em.flush() such that we can achieve atomic conversations for the
                   base form as well as the popup form! -->    
                   
                   <persistence-unit name="boBETS2">
                      <provider>org.hibernate.ejb.HibernatePersistence</provider>
                      <jta-data-source>java:/boBETSDatasource</jta-data-source>
                      <properties>
                         <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
                         <!-- <property name="hibernate.hbm2ddl.auto" value="validate"/>   -->
                         <property name="hibernate.show_sql" value="true"/>
                         <property name="hibernate.format_sql" value="true"/>
                         <property name="hibernate.generate_statistics" value="true"/>
                         <property name="jboss.entity.manager.factory.jndi.name" value="java:/boBETS2EntityManagerFactory"/>
                         <property name="hibernate.default_catalog" value="boBETS"/>
                         <property name="hibernate.default_schema" value="dbo"/>
                      </properties>
                   </persistence-unit>



                I'm not sure if I really need two PUs (i.e. one for each SMPC).  I guess I can try only one PU in persistence.xml and have both SMPCs use the same PU to see what happens.


                It would be nice if seam-gen setup interview asked will you use multiple modalPanel forms in your JSF pages for CRUD? and do this automatically although I'm not sure how many Seam devs actually do what I'm doing (i.e if this use case/UI requirement is popular or not)...