Hibernate H2 指定 drop table 命令
Hibernate H2 specify drop table order
我遇到了与 this user 几乎相同的问题。 Hibernate 无法在每次 SpringBootTest 后删除我的内存测试数据库的表(例如,当 运行 mvn test 时)。期望的行为是 ddl-auto=create-drop
,但这不起作用。
我认为原因可能是 DROP TABLE
语句的顺序无效,因此 Hibernate 会尝试删除其他表仍然依赖的表。
我的 data.sql 脚本只包含 INSERT
语句,并且模式是根据我的实体自动创建的。我尝试将 DROP TABLE
语句添加到 data.sql 的顶部,它们都通过了 (ddl-auto=create
),因为我可以指定它们必须被删除的顺序。
另一方面,我现在也必须在 data.sql 中指定模式创建..
有没有办法在不必指定模式创建的情况下指定删除语句的顺序?或者有人知道 initial problem 的解决方案吗?
编辑:
我想举个例子。我有一个与其他实体有关系的 User
实体(M:N、1:N、1:1)。创建模式时,hibernate 删除所有表,创建它们并添加约束:
// first test file:
Hibernate: drop table user if exists
... // drop other tables
Hibernate: create table user (username varchar(255) not null, ... , primary key (username))
... // create other tables
Hibernate: alter table X add constraint FKgi38hy0tsrdm332gdjrc0uhm3 foreign key (username) references user
Hibernate: alter table Y add constraint FK5svpy1b71l4jxni0xylrbbdtv foreign key (username) references user
Hibernate: alter table Z add constraint FK5a8fxbb0ug3eo1lisdrrxbbj foreign key (username) references user
// next test file:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Cannot drop "USER" because "FKGI38HY0TSRDM332GDJRC0UHM3, FK5SVPY1B71L4JXNI0XYLRBBDTV, FK5A8FXBB0UG3EO1LISDRRXBBJ" depends on it; SQL statement:
drop table user if exists [90107-200]
这个过程在第一个测试文件之后不起作用,因为它违反了约束。这就是为什么我要指定下降顺序。
我没有在我的实体上使用 CascadeType,这会导致问题吗?
您必须使用 DirtiesContext 注释您的测试 类:
@DirtiesContext(methodMode = MethodMode.BEFORE_CLASS)
这将重建测试上下文,因此也会创建-删除您的架构。
我终于找到了解决我的问题的方法。
正如我所说,错误是由试图删除其他表仍然依赖的表引起的。我认为这可能与缺少 CascadeType
规格有关,但我无法修复它。
然后我找到了 this answer,它对我有用。除了我的 data.sql
文件(我的所有数据都插入到自动创建的模式中)之外,我现在有一个 drop-tables.sql
,我可以在其中指定 DROP
语句的正确顺序。此文件在自动模式创建之前执行,因此解决了我的问题。
application.properties:
spring.jpa.properties.javax.persistence.schema-generation.database.action=drop-and-create
spring.jpa.properties.javax.persistence.schema-generation.drop-source=script-then-metadata
spring.jpa.properties.javax.persistence.schema-generation.drop-script-source=drop-tables.sql
我遇到了与 this user 几乎相同的问题。 Hibernate 无法在每次 SpringBootTest 后删除我的内存测试数据库的表(例如,当 运行 mvn test 时)。期望的行为是 ddl-auto=create-drop
,但这不起作用。
我认为原因可能是 DROP TABLE
语句的顺序无效,因此 Hibernate 会尝试删除其他表仍然依赖的表。
我的 data.sql 脚本只包含 INSERT
语句,并且模式是根据我的实体自动创建的。我尝试将 DROP TABLE
语句添加到 data.sql 的顶部,它们都通过了 (ddl-auto=create
),因为我可以指定它们必须被删除的顺序。
另一方面,我现在也必须在 data.sql 中指定模式创建..
有没有办法在不必指定模式创建的情况下指定删除语句的顺序?或者有人知道 initial problem 的解决方案吗?
编辑:
我想举个例子。我有一个与其他实体有关系的 User
实体(M:N、1:N、1:1)。创建模式时,hibernate 删除所有表,创建它们并添加约束:
// first test file:
Hibernate: drop table user if exists
... // drop other tables
Hibernate: create table user (username varchar(255) not null, ... , primary key (username))
... // create other tables
Hibernate: alter table X add constraint FKgi38hy0tsrdm332gdjrc0uhm3 foreign key (username) references user
Hibernate: alter table Y add constraint FK5svpy1b71l4jxni0xylrbbdtv foreign key (username) references user
Hibernate: alter table Z add constraint FK5a8fxbb0ug3eo1lisdrrxbbj foreign key (username) references user
// next test file:
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Cannot drop "USER" because "FKGI38HY0TSRDM332GDJRC0UHM3, FK5SVPY1B71L4JXNI0XYLRBBDTV, FK5A8FXBB0UG3EO1LISDRRXBBJ" depends on it; SQL statement:
drop table user if exists [90107-200]
这个过程在第一个测试文件之后不起作用,因为它违反了约束。这就是为什么我要指定下降顺序。
我没有在我的实体上使用 CascadeType,这会导致问题吗?
您必须使用 DirtiesContext 注释您的测试 类:
@DirtiesContext(methodMode = MethodMode.BEFORE_CLASS)
这将重建测试上下文,因此也会创建-删除您的架构。
我终于找到了解决我的问题的方法。
正如我所说,错误是由试图删除其他表仍然依赖的表引起的。我认为这可能与缺少 CascadeType
规格有关,但我无法修复它。
然后我找到了 this answer,它对我有用。除了我的 data.sql
文件(我的所有数据都插入到自动创建的模式中)之外,我现在有一个 drop-tables.sql
,我可以在其中指定 DROP
语句的正确顺序。此文件在自动模式创建之前执行,因此解决了我的问题。
application.properties:
spring.jpa.properties.javax.persistence.schema-generation.database.action=drop-and-create
spring.jpa.properties.javax.persistence.schema-generation.drop-source=script-then-metadata
spring.jpa.properties.javax.persistence.schema-generation.drop-script-source=drop-tables.sql