2 Replies Latest reply on Apr 17, 2007 12:32 PM by delphi'sghost

    Manual Flush Mode for Removing detail records

    delphi'sghost

      I'm having some problems with using flushMode to prevent auto flushing of changes to the data.

      In the example, I have a meeting object, with a one to many relationship to person objects. In the meeting editor, I have the meeting info, and the list of members, each with a remove link to remove them from the meeting. I want to be able to click the cancel button and not change anything, or the Save button which will go ahead and remove people from the meeting.

      The problem is that when I click the remove link, the removeMember method in the bean is called, and the change is flushed to the database when I don't want it to. Apart from this, everything appears to be working correctly.

      I'm using Jboss 4.0.5.GA and seam 1.2.1.GA

      So, the relevant parts of the bean is defined as :



      
      ** Incomplete bean listing , I've remove the (apparent) non-relevant stuff **
      
      import static javax.persistence.PersistenceContextType.EXTENDED;
      import javax.persistence.EntityManager;
      import javax.persistence.PersistenceContext;
      
      @Stateful
      @Scope(CONVERSATION)
      @Name("meetingEdit")
      @Transactional
      public class MeetingEditAction implements MeetingEdit {
      
       private Meeting meeting;
      
       @PersistenceContext(type=EXTENDED)
       private EntityManager em;
      
       @DataModel
       private List<Person> people;
      
      
       @Begin(flushMode=MANUAL)
       public String editMeeting() {
       --get the selected meeting and merge it with this entity manager
       setMeeting(em.merge(meetingSearch.getSelectedMeeting()));
       return "editMeeting";
       }
      
       public String removeMember(Person member) {
       log.info("removing member #0", member);
      
       if (meeting != null) {
       meeting.getMembers().remove(member);
       }
       return "success";
       }
      }
      
      
      


      In the page, I have :

      <h:dataTable value="#{meetingEdit.meeting.members}" var="member">
       <h:column>
       <h:outputText value="#{member.id}"></h:outputText>
       </h:column>
      
       <h:column>
       <h:outputText value="#{member.displayName}"></h:outputText>
       </h:column>
      
       <h:column>
       <h:commandLink value="remove" action="#{meetingEdit.removeMember(member)}"></h:commandLink>
       </h:column>
      
      </h:dataTable>
      
      




      As I said, removeMember is called (with the right member object) but the change is immediately written to the database instead of in my saveMeeting() method which includes the em.flush() call to actually make the changes.

      My understanding is that I need to be using the Hibernate persistence provider for JPA which I believe I am :

       <persistence-unit name="meetmanager">
       <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <jta-data-source>java:/meetmanagerDatasource</jta-data-source>
       <properties>
       <property name="hibernate.hbm2ddl.auto" value="update"/>
       <property name="hibernate.cache.use_query_cache" value="true"/>
       <property name="hibernate.show_sql" value="true"/>
       <property name="jboss.entity.manager.factory.jndi.name" value="java:/meetmanagerEntityManagerFactory"/>
       <property name="hibernate.default_catalog" value=""/>
       </properties>
       </persistence-unit>
      


      I'm also using the transactional seam phase listener

       <lifecycle>
       <phase-listener>
       org.jboss.seam.jsf.TransactionalSeamPhaseListener
       </phase-listener>
       </lifecycle>
      
      



      I see the hibernate SQL in the log, and I can also verify that it has been removed from the database. I have also tried setting transactional attribute to type NOT_SUPPORTED without success. Is there some other weird thing that I need to set to delay the updates until the saveMember method?

      DG

        • 1. Re: Manual Flush Mode for Removing detail records

          You appear to be using an EJB3 SFSB and a JPA extended persistence context. Only Hibernate supports a manual flush mode. What I'd assume is happening here is that your @Begin(flushMode=...) declaration is being ignored and that EJB3 is defaulting to its standard transaction/flush demarcation.

          Instead of using a JPA extended persistence context, try using a Seam managed persistence context instead. Either that or use the em.getDelegate() method, perform operations on a Hibernate Session, and manage the flushmode and flushing within your application.

          • 2. Re: Manual Flush Mode for Removing detail records
            delphi'sghost

            Thanks Captn,

            I changed the entity manager reference over to :

             @In
             private EntityManager entityManager;
            


            and it works like a charm,

            DG