9 Replies Latest reply on Mar 13, 2007 9:42 AM by lisaanm

    Auto flushing

    denis-karpov

      Hello.

      I have conversation. And at the end of this conversation i need to apply or reject changes. But after each post the flushing occurs. And all temporary changes persist to database.

      How can i switch off auto flushing?
      Or may be i misunderstand samething?

      Thanks. Denis.

        • 1. Re: Auto flushing
          gavin.king

          There are two ways to achieve this. One is to use the Hibernate-specific setting FlushModel.NEVER (or FlushMode.MANUAL).

          The other way is to make sure that all requests except for the last request run outside of a transaction context.

          ie. use Tx.NOT_SUPPORTED

          • 2. Re: Auto flushing
            ido_tamir

            Would it make any sense if pageflow would somehow support this?
            Maybe one could add an element where the transaction should begin / commit or rollback and by default be suspended or something along these lines?

            Is this a legitimate feature request?

            thanks
            ido

            • 3. Re: Auto flushing
              gavin.king

              I don't see how this has anything to do with pageflow.

              • 4. Re: Auto flushing
                ido_tamir

                Maybe I am confusing some issues, but I often have this scenario:
                a pageflow with branches, where users can create things that should be available for selection within the pageflow, but it should still be possible to cancel the whole thing or submit at the end.
                The pageflow exercises the methods of many beans and a central way to manage the transaction behavior would be nice, so I would not have to annotate all the beans/methods - or if their behavior should be different in a different context (i.e. no or different pageflow).

                thank you very much
                ido

                <?xml version="1.0" encoding="UTF-8"?>
                
                <pageflow-definition
                 name="bookFlow">
                 <start-state name="start" transaction="FlushMode.NEVER">
                 <transition name="start" to="chooseBook" transaction="begin"></transition>
                 </start-state>
                 <page name="chooseBook">
                 <transition name="createBook" to="createBook"></transition>
                 <transition name="submit" to="submit"></transition>
                 <transition name="cancel" to="cancel"></transition>
                 </page>
                 <page name="createBook">
                 <transition name="submit" to="submitBook"></transition>
                 <transition name="cancel" to="chooseBook"></transition>
                 </page>
                 <page name="submitBook">
                 <transition name="" to="chooseBook"></transition>
                 <transition name="cancel" to="chooseBook"></transition>
                 <transition name="submitted" to="chooseBook"></transition>
                 </page>
                 <page name="submit">
                 <transition name="cancel" to="cancel"></transition>
                 <transition name="submit" to="submitted"></transition>
                 </page>
                 <page name="cancel" transaction="rollback"><end-conversation/></page>
                 <page name="submitted" transaction="commit"><end-conversation/></page>
                </pageflow-definition>
                


                • 5. Re: Auto flushing
                  denis-karpov

                  Thanks for you answer.

                  Yes Ido. I need exactly what you have described. I think it is quite common scenario.

                  And how to be now?

                  With EntityManager.setFlushMode() we can set only

                  javax.persistence.FlushModeType.COMMIT

                  or
                  javax.persistence.FlushModeType.AUTO


                  I tried this:
                   private EntityManager em;
                   @PersistenceContext(type=EXTENDED)
                   public void setEntityManager(EntityManager val){
                   val.setFlushMode(FlushModeType.COMMIT);
                   em = val;
                   }
                  

                  but it does not work.
                  I get exception:
                  Caused by: java.lang.NullPointerException
                   at org.jboss.ejb3.entity.ExtendedEntityManager.getPersistenceContext(ExtendedEntityManager.java:59)
                   at org.jboss.ejb3.entity.ExtendedEntityManager.setFlushMode(ExtendedEntityManager.java:179)
                   at com.colvir.reference.action.ValutaProcAction.setEntityManager(ValutaProcAction.java:41)
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                   at org.jboss.ejb3.injection.JndiMethodInjector.inject(JndiMethodInjector.java:97)
                   ... 59 more
                  


                  Thanks. Denis.

                  • 6. Re: Auto flushing
                    lcoetzee

                    I had something similar where I wanted to reject (throw away changes that I have made to entities without it being flushed/commited to the db).

                    In the end I had to do 3 things.

                    1. in persistence.xml I prevented hibernate from flushing:

                     <property name="hibernate.transaction.flush_before_completion" value="false"/>


                    2.1. I annotated my the SFSB to prevent transactional behavior on method boundaries:
                    @Stateful
                    @Name("contentManagementBean")
                    @Conversational(ifNotBegunOutcome = "ViewContentHomePage")
                    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
                    public class ContentManagementBean implements Serializable, ContentManagement {
                    


                    2.2 The method where I had to make the choice (to accept and persist or reject and throw away everything) I annotated so that it requires a new transaction (note that no flushing would occur in any other method that is not annotated with this in this bean)
                     @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
                     public String save() throws Exception {
                    


                    3. When deciding that I want to reject and prevent flushing I also had to evict that specific object from the hibenate entity manager (this was the key for me ) and reload from the db (otherwise it might be flushed at a later stage)

                     HibernateEntityManager hem = (HibernateEntityManager)em;
                     hem.getSession().evict(metaContentInfo);
                     metaContentInfo = null;
                     MetaContentInfo mciOrig = em.find(
                     MetaContentInfo.class, mcid);
                    


                    Or something along this line.

                    Regards

                    Louis


                    • 7. Re: Auto flushing
                      gavin.king

                      You should definitely NOT have to do (1). The other steps should be enough.

                      • 8. Re: Auto flushing
                        lcoetzee

                        I will give it a try without 1.

                        Thanks

                        L

                        • 9. Re: Auto flushing
                          lisaanm

                          Hi.,
                          I was fed up with this problem of AUTO flush UPDATE and now its solved it. Thanks Icoetzee for posting the solution.