2016-07-12 119 views
1

我試圖將我的審計表保存在另一個模式,但保持與審計表相同名稱的表。我沒有問題,改變後綴或使用另一種模式,但是當我設置後綴爲空字符串,我發現了以下錯誤:休眠Envers審計表沒有後綴

Caused by: org.hibernate.DuplicateMappingException: Duplicate class/entity mapping com.logique...User 

我猜這個錯誤發生,因爲我有兩個表(但使用不同的模式),我正確設置了「org.hibernate.envers.default_schema」和「hibernate.default_schema」參數,但我並沒有預料到這個問題。

+0

因此,您在數據庫的默認模式中擁有未經審計的JPA實體,並且已經在另一個明確設置的模式中獲得了您的Envers審計實體表?什麼版本的Hibernate? – Naros

+0

Hi @Naros!再次感謝幫助=)。確切地說,我在數據庫的默認架構中擁有未經審計的實體,並且在另一個明確設置的架構中,我的Envers審計了實體表。我正在使用休眠4.3.11-FINAL –

回答

1

當Hibernate執行其元數據收集過程時,它首先讀取所有註釋的實體類並按名稱註冊它們中的每一個。此外,由於Envers處理其元數據並將該信息提供給Hibernate,Hibernate隨後將依次通過名稱註冊每個經審計的實體。

這裏的問題是,如果沒有提供後綴或前綴,Hibernate將Envers的映射視爲已註冊的實體名稱,因爲沒有前綴/後綴,它們的命名與它們生成的源實體完全相同從,導致這個錯誤。

org.hibernate.DuplicateMappingException: Duplicate class/entity mapping 

有一個解決方法,但它可能是繁瑣的,取決於您可能有審計實體的數量。我已經在5.x上測試過了,我可能懷疑這應該在4.3.x上運行。

  1. 設置audit_table_prefixaudit_table_suffix配置屬性。這是一個必須,因爲這將強制來自Envers的元數據是唯一命名爲Hibernate的可持久對象。如果不這樣做,您將繼續從上方獲取重複的映射錯誤。
  2. 對於每個審計實體,明確添加一個@AuditTable註釋,您可以在其中專門將審計表名稱設置爲與爲您的實體生成的名稱相同,無論它是基於類名還是具有名稱屬性的現有@Table

因此,作爲一個例子:

@Entity 
@Table(name = "my_table") 
@AuditTable("my_table") 
public class MyTableEntity { 
    /* stuff */ 
} 

所以用這個配置,你就可以有一個模式中你Envers表,另一個主要的實體表,這兩個模式有其表的名字相同。

希望這會有所幫助。

+0

Hi @Naros,再次感謝您的幫助,抱歉花了這麼長時間來測試您的答案。我收到兩條警告:「WARN:GenerationTarget遇到異常接受命令:無法執行命令[alter table audit.person drop constraint FK9brsg4fcuo22u7e7oxa9g1tqn]」和「WARN:GenerationTarget遇到異常接受命令:無法執行命令[drop sequence hibernate_sequence] 」。對此有何想法? –

+0

我遺留了我用來在github上測試的代碼,https:// github。com/Teless/TesteEnvers,保持儘可能簡單2類和項目描述 –

+0

兩個警告的堆棧跟蹤我相信這些警告是由於Hibernate試圖在審計表和實體表之間創建外鍵另一個模式),我說得對嗎? –