-->
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.  [ 8 posts ] 
Author Message
 Post subject: Interceptor and expiration issue...
PostPosted: Fri Jul 15, 2005 9:30 am 
Newbie

Joined: Thu Jun 30, 2005 10:35 am
Posts: 13
I am working with a historical database where rows are created instead of being updated when the state of an object changes.

I was wondering if there is a simple way to have hibernate create a new row, with the new values, when any of an object's properties change, rather than updating the existing row.

Also, the other thing I need to do is flag one boolean column in the old row to show that it is now an "expired" row.

Is there any simple way to do this with hibernate other than creating proxy classes to use with the interceptor interface? This seems like a very tedious task.

Thanks for any help!


Top
 Profile  
 
 Post subject: I've got the same problem/question
PostPosted: Fri Jul 22, 2005 5:52 pm 
Newbie

Joined: Fri Jul 22, 2005 5:46 pm
Posts: 2
Location: Zurich, Switzerland
Hi,

I'm working with temporal data, too.
Did you already find a solution for your issue?

Cheers,
Pierce


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 22, 2005 5:58 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
http://blog.hibernate.org/cgi-bin/blosx ... ggers.html


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 22, 2005 11:34 pm 
Senior
Senior

Joined: Tue Jun 21, 2005 10:18 am
Posts: 135
Location: South Carolina, USA
christian wrote:
http://blog.hibernate.org/cgi-bin/blosxom.cgi/Christian%20Bauer/relational/historytriggers.html

Christian, thanks for this. We're beginning to look into various ways of handling audit logging, and this is a very interesting technique. Not sure if it will work for us (in particular, I don't know if our old DB2/390 database can use these interception triggers"), but at a high level, I really like the concept. Just wanted to say thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 25, 2005 5:08 pm 
Newbie

Joined: Thu Jun 30, 2005 10:35 am
Posts: 13
Yes, Christian's example looks like a good option, but in our case, we didn't want to change anything at all with the database (including views), but rather to leave it all to hibernate. What I did was:

1) I created a class that implements PreInsertEventListener, where there is a method called onPreInsert which returns a boolean value to let Hibernate know whether to go on with persisting the entity or not. By changing the return to TRUE, the object will not be persisted, even though it is dirty.

2) Then I do a session.delete on the object to make it transient, but first I intercept that by having a second class which implements the Interceptor interface--there's a method in there called onDelete where I set the object's ID to 0 before making it transient.

3) Finally, I reattach the object using a session.save and Hibernate automatically makes it persistent with a new ID, which means that it will be inserted as a new row when the transaction is commited.

I see two benefits this way.. First there's no need to create a second object because it will already be blocked from updating the old row, and when the ID is zeroed and reattached with a new ID, it becomes persistent as a new row without ever needing to create a second object. And also, it is all done within one transaction and session which is a benefit in many ways as well.

Hope this helps!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 25, 2005 5:17 pm 
Newbie

Joined: Thu Jun 30, 2005 10:35 am
Posts: 13
Sorry, I made a typo... The first step above uses the PreUpdateEventListener interface, not the PreInsertEventListener.

And also, I just thought of another possible option, although I'm not positive that it will work.. It should though... You can set all the properties of the class as update="false" in the mapping rathar than using the PreUpdateEventListener and this will also block any updates from occurring.

As for the expiration of the old row, we use a timestamp column which needs to be updated, and in this kind of situation you can set that to be the only column with update="true". Then you have many options for where to change that value and once it is changed, it will be the only column that gets updated. Then you can follow the other steps to reattach the object for insertion.


Top
 Profile  
 
 Post subject: looking for sample code
PostPosted: Tue Aug 02, 2005 2:47 pm 
Newbie

Joined: Fri Jul 22, 2005 5:46 pm
Posts: 2
Location: Zurich, Switzerland
Hi 'lesuako',

would it be possible to provide me some sample code for the PreUpdateEventListener you are using? Do you have a PreDeleteEventListener, too?

Thanks,
Pierce


Top
 Profile  
 
 Post subject: Re: looking for sample code
PostPosted: Wed Aug 03, 2005 8:00 am 
Beginner
Beginner

Joined: Tue Jul 19, 2005 4:03 am
Posts: 34
Location: Aberdeen, UK
We implemented an historian based on the Audit Logging example in Chapter 8.3.2 in Hibernate in action, which may be an alternative to the Event Listener strategy.

This is what I did:
1.Created an Historizable Interface which all objects that uses the history functionality should implement (Can use just an empty interface)

2.Create an MyInterceptor class, which implements the Interceptor class

Code:
public class MyInterceptor implements Interceptor {
    private Set historySet = new HashSet();
   
    public void postFlush(Iterator iterator) {
        try {
            Iterator historyElements = historySet.iterator();
            while (historyElements.hasNext()) {
                HistoryLog.logRecord(historyElements.next());
            }
        } finally {
            historySet.clear();
        }
    }
   
    public boolean onSave(Object object, Serializable serializable, Object[] obj2, String[] str, Type[] type) {
        if (object instanceof Historizable) {
            Historizable historizable = (Historizable) object;
            historySet.add(historizable);
        }
        return false;
    }
   
    public boolean onFlushDirty(Object object, Serializable serializable, Object[] newValues, Object[] oldValues, String[] properties, Type[] type) {
        if (object instanceof Historizable) {
            Historizable historizable = (Historizable) object;
            historySet.add(historizable);
        }
        return false;
    }
   
    public void onDelete(Object obj, Serializable serializable, Object[] obj2, String[] str, Type[] type) {
        if (obj instanceof Auditable) {
            Historizable historizable = (Historizable) object;
            historySet.add(historizable);
        }
    }
   
}

(The other methods defined in the Interceptor interface uses default implementation)


3.Enabling the Interceptor by adding configuration line in the hibernate-service.xml file, by setting the SessionFactoryInterceptor attribute


Code:
<server>
    <mbean code="org.jboss.hibernate.jmx.Hibernate" name="jboss.har:service=Hibernate">
        <attribute name="DatasourceName">java:/MSSQLDS</attribute>
        <attribute name="Dialect">org.hibernate.dialect.SQLServerDialect</attribute>
        <attribute name="SessionFactoryName">java:/hibernate/SessionFactory</attribute>
        <attribute name="CacheProviderClass">org.hibernate.cache.HashtableCacheProvider</attribute>
        <attribute name="SessionFactoryInterceptor">com.saic.antares.dal.MyInterceptor</attribute>
        <attribute name="ShowSqlEnabled">false</attribute>
    </mbean>
</server>


Hope this can help you!


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