JPA DescriptorEventAdapter ChangeSet всегда нулевой

Я пытаюсь включить средство отслеживания изменений в свои объекты JPA (в файл журнала, а не в базу данных), однако набор изменений, возвращаемый моим DescriptorEventAdapter, всегда равен нулю. Я использую 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
}

постоянство.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 также возвращает Null ObjectChangeSet.


person martinyyyy    schedule 22.02.2016    source источник
comment
Будет ли это работать так, как вы ожидаете, если вы удалите аннотацию Cache?   -  person Chris    schedule 22.02.2016
comment
нет, тот же результат. Нет набора изменений   -  person martinyyyy    schedule 23.02.2016
comment
Помимо ChangeSet, заполняется ли остальная часть DescriptorEvent должным образом?   -  person Ken Clubok    schedule 27.02.2016
comment
похоже на это. запрос заполняется UpdateObjectQuery с внесенными в него изменениями. Теперь я пытаюсь получить изменения оттуда.   -  person martinyyyy    schedule 01.03.2016


Ответы (2)


Чтение event.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();
    }
}
person martinyyyy    schedule 01.03.2016

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

Это событие возникает до вычисления изменений объекта....

(Жирный шрифт — это мое дополнение.)

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

Для события после слияния возможно, что был сгенерирован набор изменений.

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

person Ken Clubok    schedule 25.02.2016
comment
Все наборы изменений, возвращаемые всеми переопределениями (postMerge, postUpdate, preUpdateWithChanges, preUpdate), равны нулю :( - person martinyyyy; 26.02.2016