在我的app启动期间,hibernate通过添加新约束来改变我的表。以下是获取问题全貌的示例代码。
Postgresql架构
create table public."A" {
a_id serial primary key
}
create table public."B" {
b_id serial primary key
}
create table public."C"(
a_id integer not null references public."A" (a_id),
b_id integer not null references public."B" (b_id),
)
数据库模型
class A{
@Id
@Column(name = "a_id")
@GeneratedValue(strategy = GenerationType.SEQUENCE)
public Integer aId;
}
class B {
@Id
@Column(name = "b_id")
@GeneratedValue(strategy = GenerationType.SEQUENCE)
public Integer bId;
}
class C {
@ManyToOne
@JoinColumn(name = "a_id")
public A a;
@ManyToOne
@JoinColumn(name = "b_id")
public B b;
}
在我的应用启动时,它再次创建约束。
Hibernate: alter table public."C" add constraint FKk4caeiw8tynv7g0p13h5inaht foreign key (a_id) references public."A"
Hibernate: alter table public."C" add constraint FK4bsokehyo37wygp12onlu8fbl foreign key (b_id) references public."B"
在DB中我看到约束已经可以使用
CONSTRAINT "C_a_id_fkey" FOREIGN KEY (a_id)
REFERENCES public."A" (a_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "C_b_id_fkey" FOREIGN KEY (b_id)
REFERENCES public."B" (b_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
除了这些,我还看到了2个新约束
CONSTRAINT FKk4caeiw8tynv7g0p13h5inaht foreign key (a_id)
REFERENCES public."A" (a_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT FK4bsokehyo37wygp12onlu8fbl foreign key (b_id)
REFERENCES public."B" (b_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
这里可能有什么问题?
答案 0 :(得分:1)
这是因为Hibernate正在比较约束名称并注意到指定名称不存在约束,因此它会重新创建它,认为它不存在。
一种解决方法是在注释中按名称手动指定约束:
@JoinColumn(name = "...", foreignKey = @ForeignKey(name = "..."))
注意:Hibernate版本高达5.2.7存在一些问题,其中某些注释不符合将外键注释值正确传递给数据库架构工具。我相信@JoinColumn
很好,但是如果不是这样的话,使用5.2.8已经引入了所有修复,以避免忽略这些注释。
另一个解决方法显然是删除现有的约束,并允许Hibernate使用自己的命名策略将其添加回来。