-->
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.  [ 4 posts ] 
Author Message
 Post subject: Interceptor propertyNames out of order?
PostPosted: Mon Jan 12, 2004 4:21 am 
Newbie

Joined: Fri Oct 31, 2003 3:33 pm
Posts: 17
Location: California
I'm writing a journalling interceptor that will selectively store column-level changes to a journal table. I'm using the findDirty() method and comparing the incoming states. While debugging, I noticed that while the currentState, previousState and types arrays are "aligned" correctly (i.e. each array element at corresponding indices refers to the same property), the propertyNames array is "off". The ordering of the first three arrays seems to be driven off the ordering of the properties in the hbm.xml file. But, the propertyNames array seems to be driven off the ordering of the getters and setters in the persisted class file.

This looks like a bug because I can "align" my bean getters/setters with my mapping file and make the code work correctly. If coerced, I suppose I could through together a "quick" main to demonstrate this phenomenon.

Here's the mapping file:

Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

   <class name="gov.llnl.ais.util.db.hibernate.JournalTestBean" table="JRNL_TEST">
      <id name="id" type="long" column="JRNL_TEST_ID">
         <generator class="sequence">
            <param name="sequence">rr.RR_GLOBAL_INTR_NO_SEQ</param>
         </generator>
      </id>
     
      <!-- properties -->
     
      <!-- "wrong" -->
      <!--
      <property name="string" column="JRNL_TEST_TXT" />
      <property name="number" column="JRNL_TEST_NO" />
      <property name="date"   column="JRNL_TEST_DT" />
      <property name="string2"   column="JRNL_TEST_TXT_2" />
      -->
      
      <!-- "right" -->
      <property name="date"   column="JRNL_TEST_DT" />
      <property name="number" column="JRNL_TEST_NO" />
      <property name="string" column="JRNL_TEST_TXT" />
      <property name="string2"   column="JRNL_TEST_TXT_2" />      

    </class>

</hibernate-mapping>


Here's the persisted class (test class):


Code:
package gov.llnl.ais.util.db.hibernate;

import java.io.Serializable;
import java.util.Date;

/**
* mapped to JRNL_TEST table to debug/test JournalInterceptor
*
* created: Jan 11, 2004 9:26:47 PM
* @author Nick Dellamaggiore
*/
public class JournalTestBean implements Serializable
{
   private static final long serialVersionUID = 1L ;
   
   private Long   id ;
   private String string ;
   private int    number ;
   private Date   date ;
   private String string2 ;

   public JournalTestBean()
   {
      super();
   }
   
   public Date getDate()
   {
      return date;
   }

   public void setDate(Date date)
   {
      this.date = date;
   }

   public Long getId()
   {
      return id;
   }

   public void setId(Long id)
   {
      this.id = id;
   }

   public int getNumber()
   {
      return number;
   }

   public void setNumber(int number)
   {
      this.number = number;
   }

   public String getString()
   {
      return string;
   }

   public void setString(String string)
   {
      this.string = string;
   }
   
   public String getString2()
   {
      return string2;
   }

   public void setString2(String string2)
   {
      this.string2 = string2;
   }
}


Here's the findDirty method:
Code:
   public int[] findDirty(
      Object entity,
      Serializable id,
      Object[] currentState,
      Object[] previousState,
      String[] propertyNames,
      Type[] types)
   {
       //localSwitch not being set means TRUE(shouldn't happen but just in case)
      if( JournallingConfig.getInstance().getGlobalSwitch() &&
          getLocalSwitch() &&
          JournallingConfig.getInstance().isJournaled( entity.getClass() ) ) {
     
         //we have some interest in this object but we still don't know if of the changed
         //properties are actually important to us, loop through them to find out.
         ArrayList journalInfoList = new ArrayList() ;
         for( int i = 0 ; i < currentState.length ; i++ ) {
            //if the property is to be journal and it has changed.
            if( JournallingConfig.getInstance().isJournaled( entity.getClass(), propertyNames[i] ) &&
                ( ( currentState[i] != null && !currentState[i].equals( previousState[i] ) ) ||
                  ( previousState[i] != null && !previousState[i].equals( currentState[i] ) ) ) ) {
               journalInfoList.add( createJournalInfo( entity, currentState[i], previousState[i], propertyNames[i], types[i]) ) ;
            }
         }
           
         if( journalInfoList.size() > 0 ) {
            for( Iterator iterator = journalInfoList.iterator() ; iterator.hasNext() ; ) {
               JournalInfo journalInfo = null ;
               try {
                  journalInfo = (JournalInfo)iterator.next() ;
                  HibernateSession.currentSession().save( journalInfo ) ;
               } catch (HibernateException e) {
                  log.error("Unable to write journalling info for " + journalInfo ) ;                   
               }
            }
         }
      }
     
      //null => default hibernate behavior     
      return null ;
   }


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2004 6:04 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I find this incredibly difficult to believe. I reckon you must be accidently manipulating the propertyNames array somewhere in your own code (not that if you do this, you change the order in the actual ClassPersister - for performance reasons, we do not pass a copy to the client (contrary to Joshua Block).


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 13, 2004 12:02 pm 
Newbie

Joined: Fri Oct 31, 2003 3:33 pm
Posts: 17
Location: California
Yeah, I figured it was something wrong with my code since something like this would have been caught way back. But, like I said, the code executing is just the stuff in the findDirty method (no array manipulation there). I am also using the AuditInterceptor in a chain with my JournalInterceptor, but the AuditInterceptor doesn't seems to do anything with the arrays.

I can leave my code alone and change either 1. the ordering in the mapping file or 2. the ordering of the getters/setters and the arrays will become aligned...this is what concerns me.

I'll try to weed out the complexity and throw a simple main together for further investigation.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 23, 2004 11:17 pm 
Newbie

Joined: Fri Oct 31, 2003 3:33 pm
Posts: 17
Location: California
I finally got around to debugging this problem. No cause for alarm here. My teammate had an Array.sort on ClassMetadata.getPropertyNames() buried in our initialization code!! That would cause some issues with the arrays being out of order. Excuse me while I go try to explain pass-by-reference concepts to my co-workers...jeez


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.