0 Replies Latest reply on Mar 31, 2008 5:58 AM by amashtakov

    EntityManager auto-flush

    amashtakov

      Hi folks,

      I'm trying to figure out how EntityManager flushes pending changes to database, but sticked with one problem - changes are automatically
      flushed to database without explicit merge(). Here is a project setup:

      1. Entity bean

      @Entity
      public class User implements java.io.Serializable {
       private Integer id;
       private String name;
      
       @Id
       @GeneratedValue
       public Integer getId() {
       return id;
       }
      
       public void setId(Integer id) {
       this.id = id;
       }
       public String getName() {
       return name;
       }
       public void setName(String name) {
       this.name = name;
       }
      }
      


      2. Stateless bean
      @Local
      public interface UserMgrLocal {
       public User findById(Integer id);
       ...
      }
      
      public class UserMgr implements UserMgrLocal {
       @PersistenceContext
       EntityManager em;
      
       public User findById(Integer id) {
       System.out.println("invoking findById ...");
       return em.find(User.class, id);
       }
       ...
      }
      


      3. Page bean (jsf action)
       ...
       public String notSave() {
       System.out.println("BEGIN notSave");
       UserManagerLocal userMgr = ... // obtained by JNDI lookup
       User u = userMgr.findById(User.class, 1);
       u.setName("kuku"); // no userMgr.save() call !!!
       System.out.println("END notSave");
       return null;
       }
       ...
      


      4. Traces
      2008-03-31 11:55:28,292 INFO [org.domain.Seam1.PageBean1] BEGIN notSave
      2008-03-31 11:55:28,292 INFO [STDOUT] invoking findById ...
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.impl.SessionImpl] opened session at timestamp: 4943682471084032
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.JDBCContext] successfully registered Synchronization
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Looking for a JTA transaction to join
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.ejb.AbstractEntityManagerImpl] Transaction already joined
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.loader.Loader] loading entity: [org.domain.Seam1.entity.User#1]
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.SQL]
       select
       user0_.id as id4_0_,
       user0_.name as name4_0_
       from
       User user0_
       where
       user0_.id=?
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.loader.Loader] result row: EntityKey[org.domain.Seam1.entity.User#1]
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.engine.TwoPhaseLoad] resolving associations for [org.domain.Seam1.entity.User#1]
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.engine.TwoPhaseLoad] done materializing entity [org.domain.Seam1.entity.User#1]
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.engine.StatefulPersistenceContext] initializing non-lazy collections
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.loader.Loader] done entity load
      2008-03-31 11:55:28,292 INFO [org.domain.Seam1.PageBean1] END notSave
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] processing flush-time cascades
      2008-03-31 11:55:28,292 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] dirty checking collections
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.event.def.AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.pretty.Printer] listing entities:
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.pretty.Printer] org.domain.Seam1.entity.User{name=kuku, id=1}
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
      2008-03-31 11:55:28,323 DEBUG [org.hibernate.SQL]
       update
       User
       set
       name=?
       where
       id=?
      2008-03-31 11:55:28,339 DEBUG [org.hibernate.jdbc.AbstractBatcher] Executing batch size: 1
      2008-03-31 11:55:28,339 DEBUG [org.hibernate.jdbc.AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
      2008-03-31 11:55:28,339 DEBUG [org.hibernate.jdbc.ConnectionManager] skipping aggressive-release due to flush cycle
      2008-03-31 11:55:28,339 DEBUG [org.hibernate.jdbc.ConnectionManager] aggressively releasing JDBC connection
      2008-03-31 11:55:28,339 DEBUG [org.hibernate.jdbc.ConnectionManager] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
      2008-03-31 11:55:28,339 DEBUG [org.jboss.ejb3.entity.ManagedEntityManagerFactory] ************** closing entity managersession **************
      


      Applying @TransactionAttribute(NOT_SUPPORTED) to UserMgr bean
      changes behaivour to desired (changes are not applied to database).
      As I understant, the persitence context is scoped to transaction
      (by default for SLSB) and hibernate EM perform flush on commit,
      BUT IMO after the execution of userMgr.findById() the transaction
      should be commited and changes shouldn't be applied to database.

      Can somebody explain why does this happen ?

      Regards,
      /Alexander