我在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 ...
}
请告诉我,如果我能提供其他任何东西来帮助你们了解这一点。我已经玩了几个小时,没有结果,你的帮助将非常受欢迎。
答案 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
作为参数)
Constraint ... already exists
将@ManyToMany
更改为@OneToMany
会完全解决此问题。
顺便说一句,违规的字段定义(带有@ManyToMany
的字段定义)以前也引起了我对Hibernate Envers'@Audited
的问题,其原因我从未理解过,现在已经解决了同样。美好的一天。 (不确定@Audited
对于映射字段是否意味着什么,但至少我可以在类上有@Audited
而无需处理此字段。)