gpt4 book ai didi

java - Hibernate 找不到正确的外键

转载 作者:行者123 更新时间:2023-11-30 08:29:17 29 4
gpt4 key购买 nike

我遇到一个问题,hibernate 试图删除不存在的外键而不是存在的外键。我的场景如下所示。

我想运行一个 junit 测试,在测试之前我想创建数据库,在测试之后我想删除它。为此,我使用 hibernate create-drop 属性。然而,棘手的部分是我想创建自己的表作为测试新添加的 sql 的一种方式,并验证它在我将它部署到生产数据库服务器后是否能正常运行。所以这是怎么回事

  • Hibernate 自动创建表
  • Hibernate 创建外键关系
  • Hibernate 运行我的删除表脚本(成功,因为没有数据,所以没有违反外键规则)
  • Hibernate 运行我的创建表脚本
  • Hibernate 运行我的添加外部约束脚本
  • Hibernate 运行我的插入数据脚本
  • 执行测试
  • Hibernate 尝试删除外键但失败了。

hibernate 无法删除它的原因是它试图删除 hibernate 创建的那个,而不是我的脚本创建的那个。

知道如何强制 hibernate 找出实际的外键吗?有什么办法可以解决这个问题?

谢谢大家

hibernate 为其创建表的类

TodoGroup.java

@Entity
@Table(name = "ToDoGroups")
public class ToDoGroup implements Serializable{


@Id
@GeneratedValue
private Long id;
@Column(name = "Name", length = 50)
private String name;
@ManyToOne
@JoinColumn(name = "UserSettingsId")
@XmlTransient
private UserSettings userSettings;
@OneToMany(mappedBy = "group", cascade = CascadeType.ALL)
private List<ToDoItem> items;

hibernate 添加约束

alter table ToDoGroups 
add constraint FK790BA1FAFE315596
foreign key (UserSettingsId)
references UserSettings

运行我自己的工作正常的表,因为没有数据,所以我可以删除 hibernate 创建的内容以验证我的 sql

DROP TABLE IF EXISTS ToDoGroups;

CREATE TABLE ToDoGroups (ID BIGINT NOT NULL IDENTITY, Name VARCHAR(50) NOT NULL, UserSettingsId BIGINT NOT NULL, PRIMARY KEY (ID));

ALTER TABLE ToDoGroups ADD FOREIGN KEY (UserSettingsID) REFERENCES UserSettings (ID);

放弃 fk 它试图执行

alter table ToDoGroups drop constraint FK790BA1FAFE315596
java.sql.SQLException: Constraint not found FK790BA1FAFE315596 in table: TODOGROUPS in statement [alter table ToDoGroups drop constraint FK790BA1FAFE315596]

尝试删除由于我在 create.sql 脚本中设置的约束而失败的表

    drop table ToDoGroups if exists
java.sql.SQLException: Table is referenced by a constraint in table SYS_REF_SYS_FK_808_810 table: TODOITEMS in statement [drop table ToDoGroups if exists]

更新

我还注意到 hibernate 在创建表之前首次启动时(所以这是在我的脚本运行之前的方式),它会尝试删除外键以删除任何存在的表。

那么hibernate怎么知道使用什么外键呢?它使用与

它执行的第一个语句

alter table ToDoGroups drop constraint FK790BA1FAFE315596

然后它删除所有的表

drop table ToDoGroups if exists

然后创建表

create table ToDoGroups (
id bigint generated by default as identity (start with 1),
Name varchar(50),
UserSettingsId bigint,
primary key (id)
)

然后它添加相同的 FK

alter table ToDoGroups 
add constraint FK790BA1FAFE315596
foreign key (UserSettingsId)
references UserSettings

我想我的问题是 hibernate 如何知道要使用什么 FK。当甚至没有表时,它在第一个 drop 语句中使用相同的 FK。后来它使用一些 FK 来创建关系。 hibernate 不应该先检查表是否存在然后尝试确定 FK 是什么吗?

最佳答案

据我了解,您的问题是您自己的脚本和 hibernate 没有使用相同的约束名称。

您可以在您的关系上使用此注释指定 hibernate 使用的约束名称:

@ForeignKey(name = "fk_UserSettings")

此外,在您的 create.sql 中:

ALTER TABLE ToDoGroups ADD CONSTRAINT fk_UserSettings FOREIGN KEY (UserSettingsID) REFERENCES UserSettings (ID);

I think my question here is how does hibernate know what FK to use. It used the same FK in the first drop statement when there was even no table. Later it used that some FK to create the relationship. Shouldn't hibernate first check if the table exists and then tries to determine what is the FK?

hibernate使用的外键名是

的拼接
"FK_" + hashcode of referenced entity name + hash code of referenced columns name on that entity.

所以它不是一个随机生成的 key (你会看到如果你改变你的实体名称它会改变)。这就是 hibernate 知道要删除的 fk 的名称的方式(hibernate 期望约束是由 hibernate 使用这个众所周知的命名策略创建的)。

Hibernate 使用约束的名称来操作它。它不会比较在与表关联的约束中编码的“规则”来查看约束是否已经存在。

关于java - Hibernate 找不到正确的外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19537918/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com