9 Replies Latest reply on Aug 18, 2009 4:00 PM by jmchiaradia

    entityManager persist with manual flush mode

      Hello,


      I have a simple question:


      Is there any way to do entityManager.persist(myEntity) and not automatically persist the entity to the database?


      I have this code, but isn't working as I spec to:


      Conversation.instance().begin(true,false);
      Conversation.instance().changeFlushMode(FlushModeType.MANUAL);
      entityManager.persist(entity);



      It automatically persist the entity and doesn't wait for entity.flush.




        • 1. Re: entityManager persist with manual flush mode

          What I really need is something like this:



          entityManager.getTransaction().begin();
          entityManager.persist(object1);
          entityManager.persist(object2);
          entityManager.getTransaction().commit();



          Could it be done?


          My first approach was to make entityManager work in MANUAL flush mode, so I could do something like this:


          Conversation.instance().begin(true,false);
          Conversation.instance().changeFlushMode(FlushModeType.MANUAL);
          ...
          entityManager.persist(object1);
          ...
          entityManager.persist(object2);
          ...
          entityManager.flush();
          Conversation.instance().end;



          With this approach, I spec that when I do entityManager.flush(); it automatically start a transaction, flush all changes to database and commit the transaction if every thing was ok. But the problem it doesn't work like I suppose to do, entityManager.persist(object1) is persisted automatically to the database and don't wait for entity.flush().


          Any help?


          Regards,
          Chiara

          • 2. Re: entityManager persist with manual flush mode
            brandonsimpson

            How are you getting the entityManager reference?


            @In EntityManager entityManager?


            There are other ways to get a reference to the entityManager that will cause behavior similar to what you are talking about.

            • 3. Re: entityManager persist with manual flush mode

              Hello,


              I am using:



              protected EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");.
              



              I cannot use @In because It need to be marked as @BypassInterceptors


              Here is Why I'm using this approach:


              http://seamframework.org/Community/JavaBeanInterceptorAndObjectInternalState

              • 4. Re: entityManager persist with manual flush mode
                asookazian

                In main(), the insert commits, so I was able to reproduce your problem.  Likely due to using @Id with @GeneratedValue in your entity class.  The 2nd example below (update) only commits if I add the em.flush().


                @Name("conversationAPI")
                @Scope(ScopeType.CONVERSATION)
                public class TestConversationAPI {
                     
                     @Logger Log log;
                     
                     @Transactional
                     public void main() {
                          EntityManager entityManager = (EntityManager) Component.getInstance("em");
                          
                          Conversation.instance().begin(true,false);
                          Conversation.instance().changeFlushMode(FlushModeType.MANUAL);
                          
                          Hotel hotel = new Hotel();
                                    
                          hotel.setName("fooname");
                          hotel.setAddress("fooaddress");
                          hotel.setCity("foocity");
                          hotel.setState("foostate");
                          hotel.setZip("foozip");
                          hotel.setCountry("USA");
                          entityManager.persist(hotel);
                          //entityManager.flush();
                          
                          Session session = (Session) entityManager.getDelegate();
                          log.info("session.getFlushMode() = "+session.getFlushMode());
                          
                     }
                
                     @Transactional
                     public void main2() {
                          EntityManager entityManager = (EntityManager) Component.getInstance("em");
                          
                          Conversation.instance().begin(true,false);
                          Conversation.instance().changeFlushMode(FlushModeType.MANUAL);
                          
                          Hotel hotel = entityManager.find(Hotel.class, new Long(1));
                          hotel.setAddress("1234 Arbi St.");
                          //entityManager.flush();
                          
                          Session session = (Session) entityManager.getDelegate();
                          log.info("session.getFlushMode() = "+session.getFlushMode());
                          
                     }
                
                
                }



                • 5. Re: entityManager persist with manual flush mode

                  Arbi,


                  This is exactly me problem, another thing to add to it is that if you are using EntityHome and you perform an update before doing an entityManager.flush, it will flush the update to db.



                  @Name("conversationAPI")
                  @Scope(ScopeType.CONVERSATION)
                  public class TestConversationAPI {
                       
                       @Logger Log log;
                       
                       @Transactional
                       public void main3() {
                            EntityManager entityManager = (EntityManager) Component.getInstance("em");
                            HotelEntityHome hotelEntityHome =  (HotelEntityHome ) Component.getInstance("hotelEntityHome");
                            Conversation.instance().begin(true,false);
                            Conversation.instance().changeFlushMode(FlushModeType.MANUAL);
                  
                            hotelEntityHome.setId((long) 1);
                            hotelEntityHome.getInstances().setName("Name Changed");
                            hotelEntityHome.update();
                  
                            Session session = (Session) entityManager.getDelegate();
                            log.info("session.getFlushMode() = "+session.getFlushMode());
                            
                       }
                  }



                  Do you have any solution to this behavior?


                  Regards,
                  Chiara



                  • 6. Re: entityManager persist with manual flush mode
                    asookazian

                    No sorry, I do not use the SAF.

                    • 7. Re: entityManager persist with manual flush mode

                      Arbi,


                      I'm not very interested in SAF, it was just another similar behavior that I found, but for the initial problem: auto flush of entityManager.persist(object) with flush mode MANUAL, do you have any solution?


                      anyone else that could help us?


                      Regards,
                      Chiara

                      • 8. Re: entityManager persist with manual flush mode
                        asookazian

                        Like I said before:


                        are you using @Id with @GeneratedValue (IDENTITY, not sequences) in your entity class(es)?  An auto-generated identity column can cause a commit even if you don't call flush() manually.  This is covered in SiA book.

                        • 9. Re: entityManager persist with manual flush mode

                          Yes!


                          I was using:


                          @Id @GeneratedValue(strategy=GenerationType.IDENTITY)



                          I will change it and try again.


                          Thanks a lot!


                          PD: Sory for the late reply, I am from Argentina and yesterday was a holiday.