Hibernate,保存对象之前的状态

发布于 2024-08-15 12:24:22 字数 263 浏览 5 评论 0原文

是否有任何普遍接受的、经过验证的使用休眠的方法可以在数据库中保留实体更改的历史记录?

我们需要跟踪相当多的对象,并且希望能够撤消对对象的更改。

我尝试使用 hibernate 的拦截器,但对象的旧状态仅在执行 merge() 时可用。大多数情况下,我们都会执行 update()saveOrUpdate()...

我目前让 warp-persist 与 Guice 一起管理会话。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不…忘初心 2024-08-22 12:24:23

我已经使用拦截器完成了此操作(基于 创建自己的拦截器空拦截器)。我能够在 onFlushDirty() 中获取所有更改(合并、保存、saveOrUpdate 和删除)。

我使用的 EmptyInterceptor 的方法:

@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 {

在 onFlushDirty( )我必须查询实体之前的状态:

Connection c = sessionFactory.getCurrentSession().connection();
Session session = sessionFactory.openSession(c);

BaseEntity newBaseEntity = (BaseEntity) object;
BaseEntity oldBaseEntity = (BaseEntity) session.get(newBaseEntity.getClass(), newBaseEntity.getId());

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());
夏花。依旧 2024-08-22 12:24:23

JBoss envers 也许就是您正在寻找的。

Envers 项目旨在实现持久类的轻松审计/版本控制。您所要做的就是使用 @Audited 注释您想要审核的持久类或其某些属性。对于每个审计实体,将创建一个表,该表将保存对该实体所做的更改的历史记录。然后,您可以毫不费力地检索和查询历史数据。

与 Subversion 类似,该库也有修订的概念。基本上,一笔交易就是一项修订(除非该交易没有修改任何已审计的实体)。由于修订版是全局的,具有修订版号,因此您可以查询该修订版的各个实体,检索该修订版数据库的(部分)视图。您可以找到带有日期的修订号,反之亦然,您可以获得提交修订的日期。

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.

亣腦蒛氧 2024-08-22 12:24:23

JBoss 开发了一个自动版本控制和审计项目:envers
我可以推荐使用它,我之前已经手动实现了审核,当您开始处理更复杂的用例时,这可能会变得非常混乱。

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.

甜嗑 2024-08-22 12:24:23

JBoss 的 Hibernate Envers 可能就是您正在寻找的:

Envers 项目旨在启用持久类的轻松审计/版本控制。您所要做的就是使用 @Audited 注释您想要审核的持久类或其某些属性。对于每个审计实体,将创建一个表,该表将保存对该实体所做的更改的历史记录。然后您就可以轻松检索和查询历史数据。

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.

寒冷纷飞旳雪 2024-08-22 12:24:23

我也遇到过同样的问题。一种解决方法是使用先前的状态进行lock(),然后使用新的状态进行merge(),而不是执行update()只是新的状态。

然后 Hibernate 知道之前/之后,并且可以在拦截器/事件侦听器中使用。

HTH。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文