Is there any generally accepted, proven-to-work way using hibernate, that keeps a history of an entitys changes in the database?
We need to keep track of quite some objects and we want to be able to undo changes to objects.
I tried using the interceptors of hibernate, but the old state of the object is only available when doing merge()
. Mostly we do update()
or saveOrUpdate()
though...
I'm currently letting warp-persist together with Guice manage the session.
I've done this with an Interceptor (creating my own based on EmptyInterceptor). I was able to get all changes (merge, save, saveOrUpdate and delete) in onFlushDirty().
The methods of EmptyInterceptor I used:
@Override
public boolean onFlushDirty(Object object, Serializable id,
Object[] newValues, Object[] oldValues, String[] properties,
Type[] types) throws CallbackException {
@Override
public boolean onSave(Object object, Serializable id, Object[] newValues,
String[] properties, Type[] types) throws CallbackException {
@Override
public void onDelete(Object object, Serializable id, Object[] newValues,
String[] properties, Type[] types) throws CallbackException {
In onFlushDirty() I had to query the previous state of the entity:
Connection c = sessionFactory.getCurrentSession().connection();
Session session = sessionFactory.openSession(c);
BaseEntity newBaseEntity = (BaseEntity) object;
BaseEntity oldBaseEntity = (BaseEntity) session.get(newBaseEntity.getClass(), newBaseEntity.getId());
JBoss envers is perhaps what you are looking for.
The Envers project aims to enable easy auditing/versioning of persistent classes. All that you have to do is annotate your persistent class or some of its properties, that you want to audit, with @Audited. For each audited entity, a table will be created, which will hold the history of changes made to the entity. You can then retrieve and query historical data without much effort.
Similarly to Subversion, the library has a concept of revisions. Basically, one transaction is one revision (unless the transaction didn't modify any audited entities). As the revisions are global, having a revision number, you can query for various entities at that revision, retrieving a (partial) view of the database at that revision. You can find a revision number having a date, and the other way round, you can get the date at which a revision was commited.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With