2014-03-03 86 views
1

我在Spring應用程序中使用了hibernate-entitymanager。我正在升級我的Hibernate版本。縮小到精確版本:當我從4.2.1.Final升級到4.2.2.Final(或任何高於此值)時,我的單元測試啓動並嘗試創建數據庫時出現以下錯誤模式:升級後出現奇怪的自引用約束衝突

2014-03-02 18:02:51,559 ERROR [SchemaExport] [main] HHH000389: Unsuccessful: alter table Incident add constraint FK_d91dua6gkdp1jn826adqss3aq foreign key (uuid) references Incident 
2014-03-02 18:02:51,559 ERROR [SchemaExport] [main] Constraint "FK_D91DUA6GKDP1JN826ADQSS3AQ" already exists; SQL statement: 

    alter table Incident 
     add constraint FK_d91dua6gkdp1jn826adqss3aq 
     foreign key (uuid) 
     references Incident [90045-170] 

的錯誤不會阻止系統工作得很好,但顯然我不能去生產,在我的系統,一個討厭的錯誤,並沒有它的解釋。

這看起來很像Incident表與表本身有外鍵關係,這是絕對不是這種情況。

我會試着在這裏Incident實體的複製本質

@Entity 
@Audited 
@EntityListeners(value = {IncidentIdentifierPrePersistListener.class }) 
@FilterDefs(...) 
@Filters(...) 
public class Incident extends SomeBaseClass { 

    @Id 
    private String uuid = UUID.randomUUID().toString(); 

    @Column(nullable = false, unique = true) 
    private long identifier; 

    ... a bunch more fields ... 
} 

請讓我知道如果我可以提供別的幫助ya'all擺脫這個光。我已經玩了好幾個小時,沒有結果,你的幫助將不勝感激。

+0

因此,您的應用程序確實需要在每次加載時執行模式導出? – gerrytan

+0

不,單元測試(H2內存數據庫)。生產將只使用模式生成來驗證模式,並且我沒有看到任何問題。但單元測試中的錯誤是值得關注的原因。只要我不明白這些錯誤,我也不會認爲生產中什麼都不會出錯。我正在升級Hibernate,這對我來說是一個紅旗。 –

+2

你可以嘗試從uuid中移除'unique = true'嗎?這是多餘的,因爲該領域已經被標記爲「@ Id」,你不覺得嗎? – gerrytan

回答

2

這裏是發生了什麼:

  • Incident定義的@ManyToOne來定義的實體Project
  • Project錯誤一個@ManyToMany回到實體Incident(應該是一個@OneToMany
  • 由於結果Hibernate產生了難以駕馭的約束:

    CONSTRAINT fk909a8f241708a1e FOREIGN KEY (uuid) 
        REFERENCES incident (uuid) MATCH SIMPLE 
        ON UPDATE NO ACTION ON DELETE NO ACTION 
    
  • Incident繼承SomeBaseClass具有@Inheritance(strategy = InheritanceType.JOINED)

  • 作爲Hibernate生成以下約束的結果:

    CONSTRAINT fk909a8f2ddd08e84 FOREIGN KEY (uuid) 
        REFERENCES somebaseclass (uuid) MATCH SIMPLE 
        ON UPDATE NO ACTION ON DELETE NO ACTION 
    
  • 作爲HHH-8217 (Make generated constraint names short and non-random)在休眠4.2.2上述兩個約束定義突然結果得到了相同的名稱(休眠只考慮了實體和th e 的外鍵約束,而不是外鍵的目標實體;注意如何generateName只需要一個Table作爲參數)

  • 並有相應的衝突:Constraint ... already exists

改變@ManyToMany@OneToMany修復了這個完全。

順便說一句,有問題的字段定義(與@ManyToMany一起)也導致了我與Hibernate Envers的@Audited問題,這是我從未理解的原因,現在也得到了解決。美好的一天。(不知道@Audited對於映射字段是否意味着很多,但是至少我可以在該類上擁有@Audited,而無需處理該字段。)