2013-07-10 90 views

回答

2

所以我想出了讓生活更輕鬆的方法是創建一個註釋來標記我有興趣進行比較的字段。沒有我最終不得不堅持命名對話,就像只使用以'get'開頭的方法一樣。我發現這種方法存在很多拐角案例。

註釋。使用

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

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

    enum CompareType { 
     string, count 
    } 

} 

它得到像

@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>(); 

    ......... 

} 

由於envers審計都設置發生變化,作爲兩個不同的事件,我不想,如果設定的修改,比較集中的對象。然後做比較,我有方法,看起來像

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); 
    } 
} 
+0

此解決方案適合您嗎? – AppSensei

+0

我想做一些非常相似的事情。 – AppSensei

+0

它一直在工作。 – denov

1

目前在Envers中沒有對此的支持。你將不得不自己比較對象。

+1

這將是巨大的,如果有一種方式來獲得在歷史表中_mod列。我發現這是一個巨大的痛苦,通過手工處理不需要的字段進行比較,休眠延遲加載和集合。也許直到那時,手冊中的一個例子會非常棒。 – denov

0

Envers API更多用於查看歷史記錄。它不會告訴你有什麼變化,但你可以獲取兩個版本並尋找差異。事實是,它不會存儲更改的內容,它會在該時間點存儲該實體的所有字段。它必須比較每一個以找出差異,因此您需要編寫該代碼。