Подтвердить что ты не робот

JPA DescriptorEventAdapter ChangeSet всегда имеет значение null

Я пытаюсь включить отслеживание изменений в мои объекты JPA (в файл журнала, а не в базу данных), однако changeSet, возвращаемый моим дескрипторомEventAdapter, всегда имеет значение null. Я использую EclipseLink 2.5.2, ojdbc6, spring -orm 4.1.1.

Все события вызываются (включая preUpdateWithChanges), и изменения переносятся в базу данных. Я использую entityManager.merge(сущность) для обновления объекта.

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>

Использование UnitOfWork из eclipse wiki также возвращает Null ObjectChangeSet.

4b9b3361

Ответ 1

Чтение события .getQuery() работает. Не знаю, почему event.getChangeSet() является emtpy, но так я его и решил.

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

В документации API для DescriptorEventAdapter.preUpdate:

Это событие поднято до. Вычисляются изменения объекта....

(Жирным шрифтом является мое дополнение.)

Из документации для DescriptorEvent.changeSet:

Для события post merge возможно создание сгенерированного набора изменений.

Что происходит при переопределении postMerge()?