Getting the old value and new value between two revisions with Hibernate Envers

ぐ巨炮叔叔 提交于 2019-11-29 16:44:49

So what I came up with to make life easier was to create an annotation to mark the fields I was interested in comparing. Without I ended up having to get with sticking to naming conversation like only only using methods that start with 'get'. I found there was a lot of corner cases with this approach.

The annotation.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface AuditCompare {

    public String name() default "";
    public CompareType compareBy() default CompareType.string;

    enum CompareType {
        string, count
    }

}

which gets used like

@Entity
@Audited
public class Guideline {

    .....

    @AuditCompare
    private String name;

    @AuditCompare
    private String owner;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true, mappedBy="guideline")
    private Set<GuidelineCheckListItem> checkListItems = new HashSet<GuidelineCheckListItem>();

    .........

}

Since envers audits both the Set changing and the object of the set as two different events I didn't want to compare if the set change. Then to do the comparison I have method that looks like

private void findMatchingValues(Object oldInstance, Object newInstance, ActivityEntry entry) {
    try {

        Class oldClass = oldInstance.getClass();
        for (Field someField : oldClass.getDeclaredFields()) {
            if (someField.isAnnotationPresent(AuditCompare.class)) {

                String name = someField.getAnnotation(AuditCompare.class).name();
                name = name.equals("") ? someField.getName() : name;

                Method method = oldClass.getDeclaredMethod(getGetterName(name));

                if(someField.getAnnotation(AuditCompare.class).compareBy().equals(AuditCompare.CompareType.count)) {
                    int oldSize = getCollectionCount(oldInstance, method);
                    int newSize = getCollectionCount(newInstance, method);
                    if (oldSize != newSize) entry.addChangeEntry(name, oldSize, newSize);

                } else {
                    Object oldValue = getObjectValue(oldInstance, method);
                    Object newValue = getObjectValue(newInstance, method);
                    if (!oldValue.equals(newValue)) entry.addChangeEntry(name, oldValue, newValue);
                }
            }
        }

    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    }
}

There's no support for that in Envers currently. You will have to compare the objects yourself.

The Envers API is more for viewing the history. It won't tell you what changed but you can fetch two revisions and looks for differences. The fact is, it doesn't store what changed, it stores all the fields of that entity at that point in time. It would have to compare each one to figure out the differences, so you will need to write that code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!