JPA DescriptorEventAdapter ChangeSet always null
Asked Answered
B

2

10

I'm trying to include a changes tracker to my JPA Entitys (to a log file, not a database) however the changeSet returned by my DescriptorEventAdapter is always null. I'm using EclipseLink 2.5.2, ojdbc6, spring-orm 4.1.1.

All events are called (including preUpdateWithChanges) and the changes are pushed to the database. I'm using entityManager.merge(entity) to update the 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) {
        ...
    }
}

Some entity

@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>

Using UnitOfWork from eclipse wiki also returns a Null ObjectChangeSet.

Bolshevik answered 22/2, 2016 at 14:19 Comment(4)
Does it work as you would expect if you remove the Cache annotation?Emmalynne
no, same result. No ChangeSetBolshevik
Apart from the ChangeSet, is the rest of the DescriptorEvent populated as expected?Unruh
seems like it. the query is filled with a UpdateObjectQuery with the changes in it. I'm now trying to get the changes from there.Bolshevik
B
4

Reading the event.getQuery() works. No idea why the event.getChangeSet() is emtpy however this is how I solved it.

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();
    }
}
Bolshevik answered 1/3, 2016 at 12:45 Comment(0)
U
0

From the API documentation for DescriptorEventAdapter.preUpdate:

This event is raised before the object's changes are computed....

(The bolding is my addition.)

From the documentation for DescriptorEvent.changeSet:

For the post merge event it is possible that there has been a change set generated.

What happens in your postMerge() override?

Unruh answered 25/2, 2016 at 1:38 Comment(1)
All changesets returned by all overrides (postMerge,postUpdate,preUpdateWithChanges,preUpdate) are null :(Bolshevik

© 2022 - 2024 — McMap. All rights reserved.