简体   繁体   中英

When are deleted entities written to the eclipselink UnitOfWorkChangeSet?

I am trying to obtain the list of deleted entities in a database operation, to implement a custom auditing. Unfortunately it is not enough to just override the remove method of the EntityManager , because of cascading deletes.

I was able to find new and updated entities by utilizing the EntityManager and its UnitOfWorkChangeSet . Curiously the list of deleted entities is always empty.

I suspect the way the client invoke the method to be problematic, but am not quite sure. The client removes items from a collection of entities of an entity by removing them on the object and than calling the persist method with the entity holding the collection. This approach works in terms of removing the objects from the database by utilizing the cascade mechanism, but I can't find the removed entities in the list of deleted objects.

Accessing deleted entities in changeset:

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());

This code is executed every time the persist method is invoked. It always returns an empty list.

Why does getDeletedObjects() always return an empty list and when does an entity get added to this list?

Management summary

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

Explanation

Disclaimer : I am bound to an ancient version (2.0.2) of eclipse-link, therefore this solution is probably outdated.

My first fault was, trying to obtain the deleted objects outside of the transaction. While this approach works for new and modified objects, it does not for deleted objects.

My second fault was trying to access the currentChanges . While debugging, I discovered, that the method getCurrentChanges() is executed on the correct change set with my deleted objects, but yields a changeset without them. Therefore it is necessary to cast the unwrapped UnitOfWork to a RepeatableWriteUnitOfWork . In later versions, it might be possible to unwrap directly to this class, as hinted by Chris . After casting, I was able to access the list of deleted objects directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM