-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: Should Session.isDirty() flushes data?
PostPosted: Tue Apr 26, 2005 9:00 am 
Newbie

Joined: Tue Apr 26, 2005 8:50 am
Posts: 1
Hello, Hibernate team.

When calling Session.isDirty() (Hibernate 3.0.0, non-classic) it looks like DefaultDirtyCheckEventListener performs actual flush. I'm not sure is this an intended behaviour. In fact, javadoc for Session.isDirty() says that it should only check are there any pending changed and would database update happen on Session.flush(). Please advise.

Thank you.

Best regards, Maxim.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Apr 26, 2005 9:17 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
sounds like either a bug in the impl or the javadoc. submit it to the jira as such.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 01, 2005 11:38 am 
Newbie

Joined: Thu Dec 16, 2004 12:27 pm
Posts: 7
Location: Long Island
I'm also running into strange behavior with isDirty(). I've run some tests and as far as I can tell, it's not that isDirty() causes flush, but it looks like it can change what does get flushed. This is all related to bug HHH-920 which I made the mistake of cloning off another, and was closed before I could submit my comment.

Below is an example.

Code:
<!-- Manuscript.manContactInfos mapping -->
<bag cascade="all-delete-orphan" inverse="true" lazy="true"
            name="manContactInfos" table="MAN_CONTACT_INFO2">
            <key column="MANUSCRIPT_ID"/>
            <one-to-many class="org.aps.eop.model.manuscript.ManContactInfo"/>       
</bag>



public void testIsDirtyDoesFlush() {
       Session session = sessionFactory().openSession();
       session.setFlushMode(FlushMode.COMMIT);
          
       try {
          Manuscript m = (Manuscript)session.createQuery
                    ("from Manuscript m where accode = ?")
                    .setParameter(0, "CNR802").uniqueResult();
             
          int oldNumContactInfos = m.getManContactInfos().size();
             
          ManContactInfo contactInfo = new ManContactInfo();
           contactInfo.setAddress("an address");
           contactInfo.setManuscript(m);
              
           m.getManContactInfos().add(contactInfo);
           
           assertTrue(session.isDirty());
              
           Transaction tx = session.beginTransaction();
              
           m.getManContactInfos().remove(contactInfo);
              
           tx.commit();
           session.clear();
              
           m = (Manuscript)session.createQuery
                    ("from Manuscript m where accode = ?")
         .setParameter(0, "CNR802").uniqueResult();
              
           //this fails but shouldn't, if call to isDirty() is commented out it passes
              assertEquals(oldNumContactInfos, m.getManContactInfos().size());
          
       } finally {
          session.close();
       }
          
}
Code:


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 01, 2005 12:43 pm 
Newbie

Joined: Thu Dec 16, 2004 12:27 pm
Posts: 7
Location: Long Island
isDirty() also seems to invoke Interceptor inconsistently. preFlush() and onFlushDirty() are triggered by isDirty(), but onSave() and onDelete() are not. Then when flush() is done, interceptor's onSave() and onDelete() are never called. Is this a bug, or is this what is expected? It makes implementing a history interceptor very difficult.

Code:
public void testIsDirtyDoesFlush4() {
      final Set inserted = new HashSet();
      final Set deleted = new HashSet();
      final Set updated = new HashSet();
      final Set postFlush = new HashSet();
      final Set preFlush = new HashSet();
   
      Interceptor interceptor = new EmptyInterceptor() {

         
         public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
            updated.add(entity);
            return false;
         }

         public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
            deleted.add(entity);
         }

         public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
             inserted.add(entity);
             return false;
         }

         public void postFlush(Iterator entities) {
            postFlush.add(new Object());
         }

         public void preFlush(Iterator entities) {
            preFlush.add(new Object());
         }

         
      };
      
      Session s = sessionFactory().openSession(interceptor);
      //s.setFlushMode(FlushMode.COMMIT);
      
      Manuscript m = (Manuscript)s.createQuery("from Manuscript m where accode = ?")
      .setParameter(0, "CNR802").uniqueResult();
      
      m.setPageCnt(m.getPageCnt() + 1);
      
      ManContactInfo contactInfo = new ManContactInfo();
      contactInfo.setManuscript(m);
      
      ManContactInfo contactInfo2 = new ManContactInfo();
      contactInfo2.setManuscript(m);

      m.setPageCnt(m.getPageCnt() + 1);
      
      try {
         assertTrue(s.isDirty());
         
         assertFalse(inserted.contains(contactInfo));
         assertFalse(inserted.contains(contactInfo2)); //not consistent with onFlushDirty
         assertTrue(updated.contains(m)); //should onFlushDirty have been called?
         assertEquals(1, preFlush.size()); //should preFlush have been called?
         assertTrue(postFlush.isEmpty());
         
         inserted.clear();
         deleted.clear();
         updated.clear();
         preFlush.clear();
         postFlush.clear();
         
         m.getManContactInfos().remove(contactInfo);
         
         s.flush();
   
         assertFalse(inserted.contains(contactInfo));
         assertFalse(inserted.contains(contactInfo2)); //onSave has been lost
         assertTrue(updated.contains(m));
         assertEquals(1, preFlush.size());
         assertEquals(1, postFlush.size());
         
      } finally {
         s.close();
      }
      
      
    }
   


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 01, 2005 12:45 pm 
Newbie

Joined: Thu Dec 16, 2004 12:27 pm
Posts: 7
Location: Long Island
BTW, My environment is Hibernate 3.05 / Java 1.4.2


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.