Hibernate Envers - 添加历史数据

Posted

技术标签:

【中文标题】Hibernate Envers - 添加历史数据【英文标题】:Hibernate Envers - Adding Historical Data 【发布时间】:2014-10-09 00:06:52 【问题描述】:

有没有办法将修订直接添加到 _AUD 表中作为历史修订?

据我了解,当实体被持久化时,环境会在 _AUD 表中创建修订记录,并将当前记录保留在实体表中。假设我想添加历史修订并且不影响实体表,这可能吗?

例如,我有一个 Person 实体

PERSON
ID | NAME 
1  | SMITH

PERSON_AUD
ID | REV | REVTYPE | NAME
1  | 1   | 0       | SMITH

我想在 PERSON_AUD 中添加以下内容而不修改 PERSON 表,因为 SMITH 是当前名称。

PERSON_AUD
ID | REV | REVTYPE | NAME
1  | 1   | 0       | SMITH
1  | 2   | 2       | JONES

【问题讨论】:

第二个版本的 Revtype 应该是 1 才能修改。 【参考方案1】:

恐怕当前的 Envers API 无法做到这一点。

【讨论】:

嗨 Adam - 我一直在研究 ValidityAuditStrategy 并且可以看到这个类负责在创建新修订时为 REVEND_TSTMP 列提供值。我可以扩展这个类来为其他列提供值,这些列要从以前的版本更新,比如 REVEND_TSTMP。能够有扩展点来实现这一点会很好,你认为这样的东西会在未来的版本中出现吗? 好吧,VAS 还做了一些其他的事情,主要与实际编写新的修订实体条目有关。如果您想添加这样的功能,创建 AuditWriter 可能更有意义,但我不确定是否会有更多人对此感兴趣。 对于我们当前的实现来说,像 RevisionListner 一样触发 Listener 是一个非常有用的功能,但它提供了以前的 revinfo。这将为我们提供一个扩展点来更新以前的 revinfo。【参考方案2】:

我的背景是 C#,但由于 Java 的框架更强大(至少我认为是这样),我相信你会找到相关的方法。

1) 将实体重新附加到会话将创建一个新修订:

private void Reattach(Person person)

    _sessionContainer.Session.Transaction.Begin();
    _sessionContainer.Session.Evict(person);
    _sessionContainer.Session.Update(person);
    _sessionContainer.Session.Flush();
    _sessionContainer.Session.Transaction.Commit();

2) 如果要操作审核条目,则需要附加一个侦听器(在本例中为预更新):

configuration.AppendListeners(ListenerType.PreUpdate, new object[]  new PreUpdateListener() );

实现的神奇之处:

public class PreUpdateListener : IPreUpdateEventListener

    public bool OnPreUpdate(PreUpdateEvent ev)
    
        var person = ev.Entity as Person;
        if (person != null)
        
            person.Name = "Jones";
        

        return true;
    

请让我知道这种方法是否适合您。

【讨论】:

嗨,Rico - 我实际上正在使用 Spring JPA 评估 Hibernate+Envers,并且真的不想在评估过程的早期就使用开箱即用的功能。在进行了一些深入的挖掘之后,我认为使用 Jdbc 编写 sql 并插入审计记录来提供服务会更容易。【参考方案3】:

您似乎忘记或不知道修订号是全局的这一事实;它在一个单独的表中进行跟踪,默认设置中称为REVINFO。修订号的每个条目也都附有时间戳。插入非自然创建的历史数据是完全错误的(根据环境甚至可能成为严重的情况)。

如果您仍想这样做,您可以使用本机 SQL 来执行此操作,方法是先在 REVINFO 中创建一个修订条目,然后在您的审计表中使用它。这是错误的。

【讨论】:

以上是关于Hibernate Envers - 添加历史数据的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate Envers

我可以使用 Liquibase 创建 Hibernate Envers 特定表吗

Hibernate Envers 将数据恢复到一个版本

将自定义字段添加到 Hibernate Envers 修订表 (revinfo),如 operation_id。哪个是操作实体的PK

Hibernate envers - 嵌套对象的加载历史

Hibernate Envers - 在启动时填写审计表