我试图在UI上向JIRA展示改变历史。我正在使用Spring Data JPA
,我已经使用Envers(v5.3.7)配置了审计跟踪。我可以使用AuditQuery
获取所有修订的列表,用于特定实体的主键值。
是否有一种简单的方法来计算修订版的“delta”并识别已更改的属性? (有新旧价值)
我已将@Audited(withModifiedFlag = true)
注释添加到我的实体类中。它在<entity>_aud
表中为每个属性添加了一个列,指示属性是否已更改。我想弄清楚,如何利用这些额外的列。
如果您需要像JIRA这样的东西,您必须自己构建它。
我建议您使用Hibernate拦截器:
http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#events
正如您在以下示例中所看到的,您将获得当前和之前的状态,然后可以创建增量并将其存储在您自己的更改日志表中:
public static class LoggingInterceptor extends EmptyInterceptor {
@Override
public boolean onFlushDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
LOGGER.debugv( "Entity {0}#{1} changed from {2} to {3}",
entity.getClass().getSimpleName(),
id,
Arrays.toString( previousState ),
Arrays.toString( currentState )
);
return super.onFlushDirty( entity, id, currentState,
previousState, propertyNames, types
);
}
}
这是我的代码
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PreUpdateEvent;
import org.hibernate.event.spi.PreUpdateEventListener;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AuditListener implements PreUpdateEventListener {
@Autowired
private EntityManagerFactory entityManagerFactory;
@PostConstruct
private void init() {
SessionFactoryImpl sessionFactory = entityManagerFactory.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
// You can also add listener for a specific entity-type instead of event-group
// In my case I needed global event listener
registry.getEventListenerGroup(EventType.PRE_UPDATE).appendListener(this);
}
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
String[] propertyNames = event.getPersister().getPropertyNames();
Object[] oldValues = event.getOldState();
Object[] newValues = event.getState();
for (int index = 0; index < propertyNames.length; index++) {
String propertyName = propertyNames[index];
Object oldValue = oldValues[index];
Object newValue = newValues[index];
// This is just sample code
boolean changed = oldValue != newValue;
if (changed) {
System.out.println("Audit log -> Property: " + propertyName + ", Old value: " + oldValue + ", New value: " + newValue);
// Actual code that persists audit log
...
...
}
}
return false;
}
}