Generating Create_Date and Update_Date Columns Using Hibernate

I am using straight Hibernate 3.0 without annotations.

When saving or updating domain objects, I would like Hibernate to automatically generate the CREATE_DT and UPDATE_DT fields, as opposed to using database triggers.

What are the best methods for doing this?

The background is that I have an object graph being passed from a client that contains multiple objects. Some of them will be inserted and others will be updated. I could set dates on the client, but that would be a bad idea. Setting the dates on the server meant I would have to shoot at the schedule and detect changes.

It seems to me that Hibernate has the ability to do this, but it doesn't jump out at me.

+2


a source to share


3 answers


The Hibernate way to do this without using triggers is to use the Hibernate event architecture and register listeners for PreInsertEvent

, PreUpdateEvent

or SaveOrUpdateEvent

(see the full package org.hibernate.event

) to set and update creation / update dates.

Another option would be to use an interceptor , either Session

-scoped or SessionFactory

-scoped, to set create and update dates to onSave(...)

and update dates to onFlushDirty(...)

.



Maybe look at this previous answer for other options.

+1


a source


The easiest way, in my opinion, to achieve this is to have these fields as properties in your object class and set them privately through your constructor. When the property value is changed, set DateUpdated (for example) to DateTime.Now (or whatever it is in Java).

Once your entity is saved, it will automatically save those dates and store them in your underlying database.



It's not directly with Hibernate, but I would have thought this solution is easier to implement than playing around with Interceptors.

Hope this helps!

0


a source


I'm checking Pascal to be the correct answer as it pointed me right to that place in the documentation, which provided detailed and example code. But for the reader, I am adding more details here.

I tried both dormant events and interceptors and found that the interceptor worked better in my situation. This was relatively easy to implement.

Thanks for the help!

Below is the code for the interceptor:

public class AuditInterceptor extends EmptyInterceptor {

    private Log log = LogFactory.getLog(this.getClass());

    private int updates;
    private int creates;

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) {
        if (entity instanceof AuditableVO) {
            creates++;
            // Find the create date and change it
            for (int i=0; i < propertyNames.length; i++) {
                if (propertyNames[i].equals("createDate")) {
                    state[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    @Override
    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) {
        if (entity instanceof AuditableVO) {
            updates++;
            // Find the update date and change it
            for (int i=0; i < propertyNames.length; i++) {
                if (propertyNames[i].equals("updateDate")) {
                    currentState[i] = new Date();
                    return true;
                }
            }           
        }
        return false;
    }
    @Override
    public void afterTransactionCompletion(Transaction tx) {
        if (tx.wasCommitted()) {
            log.info("Creations: " + creates + ", Updates: " + updates);
        }
        creates = 0;
        updates = 0; 

        super.afterTransactionCompletion(tx);
    }
}

      

0


a source







All Articles