2012-08-27 144 views
0

我有一個Web服務將持久化和刪除數據到數據庫。我想在數據庫中跟蹤哪些用戶名觸及數據庫的哪一行。在每個表中都有用於存儲用戶名的列(如果您願意,請更新列)。在表上還有一些觸發器,它們將爲該事務取用戶ID,並用試圖插入的用戶名和密碼更新該表。有沒有辦法在打開JPA,我可以得到用戶名(這將從客戶端傳遞),並更新某種JPA對象,以便當JPA持久化數據時,該用戶名將被扔到表中?OpenJPA審計功能

回答

1

其中一個最簡潔的方法是爲您的實體實現一個共同的"mapped" superclass,並使用一個包含@PrePersist註解的方法填充這些字段。

@MappedSuperclass 
public class AuditedEntity { 
    @Id protected Integer id; 
    protected String lastUpdatedBy; 

    // Setters and getters here 

    @PreUpdate 
    @PrePersist 
    public void onChange() { 
     String user = .... // Do whatever is needed to get the current user 
     setLastUpdatedBy(user); 
    } 
} 


@Entity 
public class Employee extends AuditedEntity { 
    // .... 
} 

另一種選擇是使用單獨的偵聽器:

public interface AuditedEntity { 
    public static void setLastUpdatedBy(String username); 
} 

@Entity 
@EntityListeners({ MyLogger.class, ... }) 
public class Employee implements AuditedEntity { 
    // ... 
} 

public class MyLogger { 
    @PreUpdate 
    @PrePersist 
    public void onChange(Object o) { 
     if(o instanceof AuditedEntity) { 
      String user = .... // Do whatever is needed to get the current user 
      ((AuditedEntity) o).setLastUpdatedBy(user); 
     } 
    } 

    @PostPersist 
    @PostUpdate 
    public void logChange(Object o) { 
     // Log the successful operation 
    } 
} 
+0

有什麼辦法可以設置SYS_CONTEXT(使用Oracle爲例)?我有點試圖避免使用超類。但如果我必須我會的。 – SoftwareSavant

+0

您想要在JPA代碼中清除數據庫特定的內容。您將失去將來更改數據庫引擎或使用內存數據庫進行單元測試的可能性。 – anttix

+0

如果您不想混淆mappedsuperclass(它有它自己的缺點),則可以使用偵聽器。查看關於如何更新的帖子。 – anttix