升级Hibernate后出现奇怪的自引用约束违规

时间:2014-03-03 02:19:52

标签: spring hibernate hibernate-entitymanager schemaexport

我在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 ...
}

请告诉我,如果我能提供其他任何东西来帮助你们了解这一点。我已经玩了几个小时,没有结果,你的帮助将非常受欢迎。

1 个答案:

答案 0 :(得分: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
    
  • 由于Hibernate 4.2.2中的HHH-8217 (Make generated constraint names short and non-random),上面两个约束定义突然得到了相同的名称(Hibernate只考虑实体和外键约束的,而不是外键的目标实体;请注意generateName只需要一个Table作为参数)

    < / LI>
  • 还有相应的冲突:Constraint ... already exists

@ManyToMany更改为@OneToMany会完全解决此问题。

顺便说一句,违规的字段定义(带有@ManyToMany的字段定义)以前也引起了我对Hibernate Envers'@Audited的问题,其原因我从未理解过,现在已经解决了同样。美好的一天。 (不确定@Audited对于映射字段是否意味着什么,但至少我可以在类上有@Audited而无需处理此字段。)