-->
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.  [ 3 posts ] 
Author Message
 Post subject: Issues with findDirty method when using many to one mapping
PostPosted: Sun Jun 27, 2010 5:17 am 
Newbie

Joined: Tue Jun 22, 2010 2:54 am
Posts: 3
Hi ,
I have written a custom MergeEventListener by sub-classing the DefaultMergeEventListener and overriding its onMerge(MergeEvent event) method .

My goal is to compare the pre-update db snapshot of an entity with the currently changed entity(the entity that is currently registered with the session ) .My goal is that , if there is a difference some processing will be done .

I am elaborating this part a little bit ,
say I have a record Course ( course_id:1, name:"First Course" ) . This is already saved in DB .Now I have loaded the course object using hibernate session and made a change and invoked merge on it .
Lets assume now its state is ( course_id:1, name:"First Course Changed " ) . This is where I want to track the change .For this what I am doing is mentioned below :

Code:
Object originalEntity = event.getOriginal();
EventSource source = event.getSession();
String entityName = source.getEntityName(originalEntity);
EntityPersister persister = source.getEntityPersister(entityName, originalEntity);
EntityMode entityMode = persister.guessEntityMode(originalEntity);
final Serializable entityId = ((AbstractBO)originalEntity).getId();

Object[] oldState = persister.getDatabaseSnapshot(entityId, source);
Object[] newState = persister.getPropertyValues(originalEntity, entityMode);
// Compare the two snapshots
int[] dirtyArray = persister.findDirty(oldState, newState, originalEntity, source);


As you can see above , persister.getDatabaseSnapshot is for getting the preupdated state and persister.getPropertyValues is providing changed entity state (both of them are proving object arrays ) and then finally I am invoking persister.findDirty method , which is returning me indices of all dirty properties.

This is working fine for me . But when my mapping is changed a little bit with another many to one attribute , I am facing an issue .

For example I have one parent entity named Node and the structure becomes like the following
Node [node_id,name] --->Course[course_id,name]

[Node is basically an entity with table per subclass mapping ]
Then naturally course has a many to one mapping to the parent node .

While a many to one mapping is added , my code throws the exception
--------Exception start ---------
org.hibernate.HibernateException: Unable to resolve entity name from Class [java.lang.Long] expected instance/subclass of [com.ibm.lk.domain.portfolio.NodeBO]

--------Exception end---------

I have checked the exception with Hibernate 3.5.3 source code , it is showing that the exceptions starts from :
org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3392).

The reason as far as I understand , the oldstate[] passed to findDirty method by using the method
Code:
Object[] oldState = persister.getDatabaseSnapshot(entityId, source);

has an entry of a Long object with value 2 [That is the node_id value of Parent object ] whereas the newState array has an object entry of NodeBO object .

Code:
Object[] newState = persister.getPropertyValues(originalEntity, entityMode);


This difference of just the Long object (i.e. the object type of the primary key of the parent entity ) and the Node object is leading to the exception .

If I do not have the many to one mapping everything is OK.But otherwise I face this problem.
Any suggestions , so that I can use the findDirty method preperly with many to one cases with table per subclass mapping also ?

Regards,
Ayan


Top
 Profile  
 
 Post subject: Re: Issues with findDirty method when using many to one mapping
PostPosted: Tue Jun 29, 2010 1:21 am 
Newbie

Joined: Tue Jun 22, 2010 2:54 am
Posts: 3
Hi ,
Any update from anybody ? I am willing to know where I am doing the mistake . One thing also came to my mind , I am explaining that below ...
As the main problem seems to be (please correct me if am wrong ) the difference in the representation of a particular element inside Object[] oldState and Object[] newState.
oldState array has many to one entity representation as a Long object (i.e. id of the node object) whereas newState array contains the object itself i.e.(com.domain.portfolio.NodeBO) .
This is where the mismatch starts and it ultimately leads to the problem inside findDirty method . What if I can provide the findDirty with correct type of object arrays ?

Let me show you the mapping files ..
Course.hbm.xml
Code:
<class name="com.domain.course.CourseBO" table="COURSE" >
        <id name="id" column="COURSE_ID" >
            <generator class="increment" />
        </id>
   
       <version name="version"/>
       
        <property name="courseNumber" column="COURSE_NUM" length="100" />     
        <property name="courseName" column="CRSE_NAME" length="500" />
         
        <many-to-one name="parent" column="NODE_ID" ></many-to-one>
......

Node.hbm.xml
Code:
<class name="com.domain.portfolio.NodeBO" table="NODE">
    <id name="id" type="long" column="NODE_ID">
        <generator class="increment"/>
    </id>
    <discriminator column="NODE_TYPE" type="string"/>
       <set name="courses" cascade="all" inverse="true" >
      <key column="NODE_ID"></key>
      <one-to-many class="com.domain.course.CourseBO"/>
   </set>
   
    <many-to-one name="parent" column="PARENT_NODE_ID"  class="com.domain.portfolio.NodeBO" lazy="false">
    </many-to-one>   
       
    <subclass name="com.domain.portfolio.PortfolioBO" discriminator-value="Level2">
     </subclass>     
    <subclass name="com.domain.portfolio.PortfolioFamilyBO" discriminator-value="Level1">   
    </subclass>     
</class>


What I thought if I change the many to one association from
Code:
<many-to-one name="parent" column="NODE_ID" ></many-to-one>
to
Code:
<many-to-one name="parent" column="NODE_ID" lazy="false"></many-to-one>
, then may be the line
Code:
Object[] oldState = persister.getDatabaseSnapshot(entityId, source);
will fill up the oldState [] with the many to one object instead of its id .But that was not case .

Any idea what can be done ? or do we have any alternative of persister.getDatabaseSnapshot to get oldState [] filled up with actual objects instead of ids ?

Regards,
Ayan


Top
 Profile  
 
 Post subject: Re: Issues with findDirty method when using many to one mapping
PostPosted: Thu Jul 08, 2010 10:57 am 
Newbie

Joined: Tue Jun 22, 2010 2:54 am
Posts: 3
Any update regarding this topic from anybody ?


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