对象保存以后,如何精准获取对应AUDIT_ENTITY_LOG表的这条变更记录数据

我在保存对象后,就去查询AUDIT_ENTITY_LOG表,想获取前后变化的日志数据,,但是我发现有时候我查询AUDIT_ENTITY_LOG表的时候,修改对象后日志审计记录还没有插入表中。。。我如何能保存对象后准确查询到这条对象的AUDIT_ENTITY_LOG日志数据?是不是只能通过创建人和实体名称进行倒序查询取第一条?但是我发现这样不准,有时我查询的时候,日志数据还没有插入AUDIT_ENTITY_LOG表。。。。有没有保存对象后返回此条数据变更的AUDIT_ENTITY_LOG日志数据?

你好!能否尽快回答一下,因为是线上问题比较急!!!

你好,这里是Jmix免费论坛,我们有尽最大努力回答社区的问题。如果你需要及时的支持,请使用我们的商业支持服务:咨询 – Jmix

Audit 组件安装后,源代码在 IDEA 里面是可以看到的。实体日志的实现类是 EntityLogImpl.java,查看这个文件你会发现:

  1. EntityLogItem 并不是马上写数据库,而是先放入一个队列中。
  2. 在保存 EntityLogItem 之前, 会发送一个 EntitySavingEvent
    image

所以,你可以写一个 EventListener 拿到保存前的 EntityLogItem:

@Component("leot_EntityLogItemEventListener")
public class EntityLogItemEventListener {

    @TransactionalEventListener
    public void onEntityLogItemSaving(final EntitySavingEvent<EntityLogItem> event) {
        var entity = event.getEntity();
    }
}

我有什么方法,能判断是否已经入库了?或者我怎么等待入库以后再进行相关查询操作?

可以按照 文档 的说明,扩展一下 EntityLogImpl。重写 saveItem(EntityLogItem item) 方法,把原来的方法内容复制过来。在 每个 entityManager.persist(item) 后面加上 flush() 和发送实体保存成功事件的代码。如:

entityManager.persist(item);
entityManager.flush();
applicationEventPublisher.publishEvent(new EntityChangedEvent<EntityLogItem>(this, Id.of(item), EntityChangedEvent.Type.CREATED, null, metadata.getClass(item)));

然后可以监听 EntityChangeEvent

@Component("leot_EntityLogItemChangedEventListener")
public class EntityLogItemChangedEventListener {

    @Autowired
    private DataManager dataManager;

    @TransactionalEventListener
    public void onEntityLogItemChangedAfterCommit(final EntityChangedEvent<EntityLogItem> event) {
        var entity = dataManager.load(event.getEntityId()).joinTransaction(false).one();
    }
}