【问题标题】:JPA DescriptorEventAdapter ChangeSet always nullJPA DescriptorEventAdapter ChangeSet 始终为空
【发布时间】:2016-06-04 00:25:01
【问题描述】:

我正在尝试将更改跟踪器包含到我的 JPA 实体(到日志文件,而不是数据库)中,但是我的 DescriptorEventAdapter 返回的 changeSet 始终为空。我正在使用 EclipseLink 2.5.2、ojdbc6、spring-orm 4.1.1。

调用所有事件(包括 preUpdateWithChanges)并将更改推送到数据库。我正在使用 entityManager.merge(entity) 来更新实体。

HistoryEventListener.java

public class HistoryEventListener extends DescriptorEventAdapter {
    @Override
    public void preUpdate(DescriptorEvent event) {
        ObjectChangeSet changeSet = event.getChangeSet(); // Always null
    }

    @Override
    public void preUpdateWithChanges(DescriptorEvent event) {
        ObjectChangeSet changeSet = event.getChangeSet();
        ...
    };

    @Override
    public void postUpdate(DescriptorEvent event) {
        ...
    }

    @Override
    public void postMerge(DescriptorEvent event) {
        ...
    }
}

一些实体

@Entity
@Table(name = "XXX", schema = "XXX")
@EntityListeners(HistoryEventListener.class)
@Cache(databaseChangeNotificationType = DatabaseChangeNotificationType.NONE, isolation = CacheIsolationType.ISOLATED)
public class XXXX implements Serializable {
  // id + fields
}

persistence.xml

<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="XXXXXX"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/XXXXX</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.weaving" value="static" />
            <property name="eclipselink.target-database" value="Oracle11" />
        </properties>
    </persistence-unit>
</persistence>

使用 eclipse wiki 中的 UnitOfWork 也会返回 Null ObjectChangeSet。

【问题讨论】:

  • 如果您删除 Cache 注释,它是否可以正常工作?
  • 不,同样的结果。没有变更集
  • 除了 ChangeSet 之外,DescriptorEvent 的其余部分是否按预期填充?
  • 好像是这样。查询中填充了带有更改的 UpdateObjectQuery。我现在正试图从那里获取更改。

标签: java jpa eclipselink spring-orm


【解决方案1】:

阅读 event.getQuery() 有效。不知道为什么 event.getChangeSet() 是空的,但这就是我解决它的方法。

public void preUpdateWithChanges(DescriptorEvent event) {
    if (event.getQuery() instanceof UpdateObjectQuery) {
        UpdateObjectQuery query = (UpdateObjectQuery) event.getQuery();
        for (ChangeRecord cr : query.getObjectChangeSet().getChanges()) {
            String clazz = query.getObject().getClass().getSimpleName();
            Object id = query.getObjectChangeSet().getId();
            Object newValue = PropertyUtils.getProperty(query.getObject(), cr.getAttribute());
            Object oldVal = cr.getOldValue();
    }
}

【讨论】:

    【解决方案2】:

    来自 DescriptorEventAdapter.preUpdate 的 API 文档:

    在计算对象的更改之前引发此事件....

    (粗体是我的补充。)

    来自 DescriptorEvent.changeSet 的文档:

    对于 post merge 事件,可能生成了更改集。

    你的 postMerge() 覆盖会发生什么?

    【讨论】:

    • 所有覆盖(postMerge、postUpdate、preUpdateWithChanges、preUpdate)返回的所有变更集都为空:(
    猜你喜欢
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多