2014-03-03 53 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,而无需处理该字段。)