在我当前的项目中,我有一个可以发布到其他系统的实体。为了跟踪出版物,实体有一个称为“出版物”的关系。我正在使用 Eclipselink。
这个实体 bean 也有一个“PreUpdate”注解的方法。
为了能够使其他系统数据保持最新,我创建了一个围绕 PreUpdate 方法的调用执行的 Aspect。根据更改了哪些属性,我需要删除一些出版物。一切正常。
我遇到的问题是门户发布组件正确发送删除命令并从实体“发布”列表中删除发布。我什至可以在变更集中看到 JPA 注意到“publications”属性发生了变化。刷新事务后,缓存实体正确地不再具有已删除的发布。不幸的是,数据库仍然存在,当系统重新启动或再次从数据库加载实体时,发布元数据再次出现。
我几乎什么都试过了。我什至设法从 Aspect 中的 JPA ChangeSet 中获取已删除的实例,并尝试使用 entityManager 手动删除它们,但实际上没有任何效果。我似乎无法删除这些关系实体。目前我正在考虑使用 JDBC 来删除它们,但这只是我最后的措施。
@Transactional
@Around("execution(* de.cware.services.truck.model.Truck.jpaPreUpdate(..))")
public Object truckPreUpdate(final ProceedingJoinPoint pjp) throws Throwable {
    if (alreadyExecutingMarker.get() != Boolean.TRUE) {
        alreadyExecutingMarker.set(Boolean.TRUE);
        final Truck truck = (Truck) pjp.getTarget();
        final JpaEntityManager jpaEntityManager = (JpaEntityManager) entityManager.getDelegate();
        final UnitOfWorkChangeSet changeSet = jpaEntityManager.getUnitOfWork().getCurrentChanges();
        final ObjectChangeSet objectChangeSet = changeSet.getObjectChangeSetForClone(truck);
        if (log.isDebugEnabled()) {
            log.debug("--------------------- Truck pre update check (" + truck.getId() + ") ---------------------");
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // If the truck date has changed, revoke all publication copies.
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        final ChangeRecord truckFreeDate = objectChangeSet.getChangesForAttributeNamed("lkwFreiDatum");
        if (truckFreeDate != null) {
            if (log.isDebugEnabled()) {
                log.debug("The date 'truckFreeDate' of truck with id '" + truck.getId() + "' has changed. " +
                        "Revoking all publications that are not marked as main applications");
            }
            for (final String portal : truck.getPublishedPortals()) {
                if (log.isDebugEnabled()) {
                    log.debug("- Revoking publications of copies to portal: " + portal);
                }
                portalService.deleteCopies(truck, portal);
                // Get any deleted portal references and use the entityManager to finally delete them.
                changeSet = jpaEntityManager.getUnitOfWork().getCurrentChanges();
                objectChangeSet = changeSet.getObjectChangeSetForClone(truck);
                final ChangeRecord publicationChanges = objectChangeSet.getChangesForAttributeNamed("publications");
                if (publicationChanges != null) {
                    if (publicationChanges instanceof CollectionChangeRecord) {
                        final CollectionChangeRecord collectionChanges =
                                (CollectionChangeRecord) publicationChanges;
                        @SuppressWarnings("unchecked")
                        final Collection<ObjectChangeSet> removedPublications =
                                (Collection<ObjectChangeSet>)
                                        collectionChanges.getRemoveObjectList().values();
                        for (final ObjectChangeSet removedPublication : removedPublications) {
                            final TruckPublication publication = (TruckPublication) ((org.eclipse.persistence.internal.sessions.ObjectChangeSet) removedPublication).getUnitOfWorkClone();
                            entityManager.remove(publication);
                        }
                    }
                }
            }
        }
    }
}
克里斯