EclipseLink Audit / History / Track changes

2020-07-18 03:31发布

问题:

i've tried to implement a way to track data changes and create a history log for my application. Because i'm using EclipseLink it should be easy and possible to get the changes like they write on the EclipseLink FAQ The first solution works but the second event based won't work. Everytime the event is raised the ObjectChangeSet is null.

The reason why i'm not simply using HistoryPolicy is that i wan't to store information about the logged on user (not the db user) and the changed data to a separate table. I searched a lot but can't find any solution to this problem.

This is my entity class:

@Entity
@EntityListeners(HistoryEventListener.class)
@Table(name = "t_users")
    public class Users implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GENSEQ_USERS")
@SequenceGenerator(name = "GENSEQ_USERS", sequenceName = "SEQ_USERS", allocationSize = 1, initialValue = 1)
private Integer id;
@Column(nullable = false)
private String userid;
...
}

And this is my DescriptorEventAdapter class:

public class HistoryEventListener extends DescriptorEventAdapter {

@Override
public void postUpdate(DescriptorEvent event) {
    ObjectChangeSet changeSet = event.getChangeSet();
    if (changeSet != null) {
        System.out.println("ObjectChangeSet not null");
    }
    System.out.println("ObjectChangeSet null");
}

@Override
public void postMerge(DescriptorEvent event) {
    ObjectChangeSet changeSet = event.getChangeSet();
    if (changeSet != null) {
        System.out.println("ObjectChangeSet not null");
    }
    System.out.println("ObjectChangeSet null");
}
}

The persistence.xml file which i've used:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="PhoneBookPU" transaction-type="RESOURCE_LOCAL">
    <provider>
        org.eclipse.persistence.jpa.PersistenceProvider
    </provider>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@somehostname:1521:xyz"/>
        <property name="javax.persistence.jdbc.password" value="getyourown"/>
        <property name="javax.persistence.jdbc.user" value="username"/>
        <property name="javax.persistence.logging.level" value="INFO"/>
    </properties>
</persistence-unit>
</persistence>

Any help would be much appreciated.

回答1:

Looks like the change set is only set for the merge event, not the postUpdate. Please log a bug to have the change sets added to the pre/postUpdate events.

You can also get the ChangeSet from the query or object,

((UpdateObjectQuery)event.getQuery()).getObjectChangeSet()

or,

((AttributeChangeListener)((ChangeTracker)event.getObject())._persistence_getPropertyChangeListener()).getObjectChangeSet()