【问题标题】:When are deleted entities written to the eclipselink UnitOfWorkChangeSet?何时将删除的实体写入 eclipselink UnitOfWorkChangeSet?
【发布时间】:2019-02-10 11:50:27
【问题描述】:

我正在尝试获取数据库操作中已删除实体的列表,以实现自定义审核。不幸的是,仅仅覆盖EntityManagerremove 方法是不够的,因为级联删除。

通过使用EntityManager 及其UnitOfWorkChangeSet,我能够找到新的和更新的实体。奇怪的是,被删除实体的列表总是空的。

我怀疑客户端调用方法的方式有问题,但不太确定。客户端从实体的实体集合中移除项目,方法是在对象上移除项目,然后使用持有该集合的实体调用 persist 方法。这种方法通过利用级联机制从数据库中删除对象,但我无法在已删除对象列表中找到已删除的实体。

访问变更集中已删除的实体:

Map<ObjectChangeSet, ObjectChangeSet> deletedObjects =
        entityManager.unwrap(UnitOfWork.class)
        .getCurrentChanges()
        // returns always an empty list
        .getDeletedObjects();

  return deletedObjects.values().stream()
        .map(v -> v.getUnitOfWorkClone())
        .collect(Collectors.toList());

每次调用persist 方法时都会执行此代码。它总是返回一个空列表。

为什么getDeletedObjects() 总是返回一个空列表以及实体何时添加到该列表中?

【问题讨论】:

  • 尝试在 EntityManager 上调用 flush,然后在展开 UnitOfWork 后调用 getUnitOfWorkChangeSet 或在展开到 RepeatableWriteUnitOfWork 后调用 getCumulativeUOWChangeSet。
  • 这也不起作用。 getDeletedObjects() 仍然返回一个空列表。

标签: java jpa eclipselink audit-logging


【解决方案1】:

管理总结

entityManager.getTransaction().begin();
entityManager.delete(entity);
final Map deletedObjects = 
    ((RepeatableWriteUnitOfWork) entityManager
        .unwrap(UnitOfWork.class)).getDeleted();
// process deleted objects
entityManager.getTransaction().commit();

说明

免责声明:我绑定的是 eclipse-link 的一个古老版本(2.0.2),因此这个解决方案可能已经过时了。

我的第一个错误是,试图在事务之外获取已删除的对象。虽然这种方法适用于新的和修改过的对象,但不适用于已删除的对象。

我的第二个错误是试图访问currentChanges。在调试时,我发现 getCurrentChanges() 方法是在使用我删除的对象的正确更改集上执行的,但会产生一个没有它们的更改集。因此有必要将解包的UnitOfWork 转换为RepeatableWriteUnitOfWork。如Chris 所暗示的,在以后的版本中,可能可以直接解包到此类。投射后,我可以直接访问已删除对象的列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-29
    • 2021-04-06
    相关资源
    最近更新 更多