Hibernate, save the previous state of an object

帅比萌擦擦* 提交于 2019-11-30 16:05:00

问题


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.


回答1:


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());



回答2:


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.



回答3:


Hibernate Envers from JBoss is probably 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.




回答4:


There is an automatic versioning and auditing project developed by JBoss: envers. I can recommend using this, I've implemented auditing by hand before and that can get really messy when you start approaching more complex usecases.




回答5:


I've had exactly the same problem. One way round it is to lock() with the previous state and then merge() with the new state, rather than doing update() with just the new state.

Then hibernate is aware of the before/after and it is available in the interceptors/event listeners.

HTH.



来源:https://stackoverflow.com/questions/1927098/hibernate-save-the-previous-state-of-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!