Plan
I use Hibernate to implement createDate and lastUpdate Timestamps for a small project. I use EmptyInterceptor and overload the provided methods based on the proposed solution that I found here . The solution works just fine, if only a small detail. I want to add a column indicating whether the object has already been updated. I know that I can achieve this by simply comparing if there is a difference in the two created and updated timestamps, but I need this field to indicate an update.
I use the onSave method, which is called when a new object is stored to set the isUpdated value to "N", which indicates that there is no update. In the onFlushDirty () method, I set this value to "Y".
Problem
I would use expext when I create and save a new object, that the createDate and lastUpdate fields have the same date, but the isUpdated field has a value of "N" since there was no update. I use session.save () in my code, there is no session.update (), and also no session.saveOrUpdate (). Hibernate logs show that there is actually an update that sets the isUpdated value to "Y".
What could be the source of this update? Where does it work?
Initializing and saving objects
I disabled auto-commit in hibernate.cfg.xml.
<property name="hibernate.connection.autocommit">false</property>
This is how I create the object:
ExampleObject ex = new ExampleObject(); ex.setValue("TestStringValue"); this.session = HibernateUtil.getSessionFactory().openSession(); this.session.beginTransaction(); this.session.save(ex); this.session.getTransaction().commit(); this.session.close();
Interceptor
@Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { if (entity instanceof TimeStamped) { Date insertDate = new Date(); int indexOfCreateDateColumn = ArrayUtils.indexOf(propertyNames, "createdDate"); int indexOfUpdatedDateColumn = ArrayUtils.indexOf(propertyNames, "lastUpdatedDate"); int indexOfWasUpdated = ArrayUtils.indexOf(propertyNames, "wasUpdated"); state[indexOfCreateDateColumn] =insertDate; state[indexOfUpdatedDateColumn] =insertDate; state[indexOfWasUpdated] ='N'; return true; } return false; }
The second way is to set lastUpdatedDate and set the isUpdated field to "Y".
@Override public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { if (entity instanceof TimeStamped) { int indexOfLastUpdate = ArrayUtils.indexOf(propertyNames, "lastUpdatedDate"); int indexOfWasUpdated = ArrayUtils.indexOf(propertyNames, "wasUpdated"); currentState[indexOfLastUpdate] = new Date(); currentState[indexOfWasUpdated] ='Y'; return true; } return false; }
Hibernateutil
I use this configuration for the session.
public class HibernateUtil { private static SessionFactory sessionFactory; private static ServiceRegistry serviceRegistry; static { try { Configuration configuration = new Configuration().setInterceptor(new TimeStampInterceptor()); configuration.configure(); serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); } catch (HibernateException he) { System.err.println("Error creating Session: " + he); throw new ExceptionInInitializerError(he); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
Version
I am using Maven and Java 1.7.0_40.
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.4.Final</version> </dependency>