我们有一个具有String属性的实体,可能会经常更改,因此我们使用了@NotAudited
。但这会导致列在审计表中为空(可以理解)。
如果实体(其中一个已审计的列)发生更改,但我们希望将String属性的实际值插入审计表,但是如果所述字符串不希望将新记录插入审计表中财产变化。
我该怎么做?
答案 0 :(得分:2)
您所描述的是我们所称的条件审核,您可以在Envers文档中找到详细信息。
基本原则是您继续使用@Audited
注释该属性,但确定在PostUpdateEvent
期间是否有任何其他属性更改,如果您的特定属性已更改,则您不会将PostUpdateEvent
委托给Envers默认侦听器实现。
某些伪代码可能如下所示:
public class CustomEnversPostUpdateEventListener
extends EnversPostUpdateEventListenerImpl {
public CustomEnversPostUpdateEventListener(EnversService enversService) {
super( enversService );
}
@Override
public void onPostUpdate(PostUpdateEvent event) {
final String entityName = event.getPersister().getEntityName();
if ( getEnversService().getEntityConfigurations().isVersioned( entityName ) ) {
if ( MySpecialEntity.class.getName().equals( entityName ) ) {
// Compare event.getState() against event.getOldState()
// Determine if only your special String changed or not
if ( !otherFieldsChangedBesidesSpecialProperty ) {
return;
}
}
// delegate to default implementation
super.onPostUpdate( event );
}
}
}
此次写入时所需的方法要求您也覆盖EnversIntegrator
内的侦听器注册。扩展这些监听器,需要有关状态比较的工作知识,这给用户带来了沉重的负担,而不是提供可插拔的解决方案。
可插拔解决方案是HHH-11326背后的目标。我想介绍的是类似JPA的概念,其中@AuditListener
可以放在审计的实体类上,而Envers则会委托给侦听器实现这种行为。
关于这将如何发挥作用尚无定论,所以以下仅仅是我个人对这个问题的思考以及它如何看待和发挥代码的大脑:
public class MyEntityAuditListener extends AbstractAuditListener {
@Override
public boolean onPostUpdate(EnversPostUpdateEvent event) {
// return true = allow the audit operation
// return false = veto the audit operation
if ( event.getPropertyChangeCount() != 1 ) {
return true;
}
return !event.isPropertyChanged( "mySpecialString" );
}
}
@Entity
@Audited
@AuditListener(MyEntityAuditListener.class)
public class MyEntity {
// ...
private string mySpecialString;
}
好的部分是EnversPostUpdateEvent
允许我们抽象出许多Envers内部构件,暴露出一个干净的API,允许用户轻松决定是否否决审计操作而不必知道很多关于Hibernate事件或Envers内部的工作原理。
正如JIRA指出的那样,我计划在未来几个月内在Hibernate Envers 6.0的下一个主要版本中引入这个新的@AuditListener
概念。