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 - 添加历史数据的主要内容,如果未能解决你的问题,请参考以下文章
我可以使用 Liquibase 创建 Hibernate Envers 特定表吗
将自定义字段添加到 Hibernate Envers 修订表 (revinfo),如 operation_id。哪个是操作实体的PK