enh*_*ack 2 testing hibernate h2 unique-constraint spring-boot-test
我有一个简单的 Spring Boot (2.6.1) 测试,它抛出:
JdbcSQLIntegrityConstraintViolationException:
Unique index or primary key violation
Run Code Online (Sandbox Code Playgroud)
该测试从 加载数据test/resources/data.sql,其中只有一条语句:
INSERT INTO country (name) VALUES ('Italy');
Run Code Online (Sandbox Code Playgroud)
测试类是:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FailingTest {
@Test
@Sql("/data.sql")
void test(){
assertTrue(true);
}
}
Run Code Online (Sandbox Code Playgroud)
域类是:
@Entity
public class Country {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
@Column(nullable = false, unique = true)
private String name;
}
Run Code Online (Sandbox Code Playgroud)
该application.properties文件包含:
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.defer-datasource-initialization=true
Run Code Online (Sandbox Code Playgroud)
异常消息是:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException:
Failed to execute SQL script statement #1 of class path resource [data.sql]:
INSERT INTO country (name) VALUES ('Italy');
nested exception is org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException:
Unique index or primary key violation:
"PUBLIC.UK_LLIDYP77H6XKEOKPBMOY710D4_INDEX_6 ON PUBLIC.COUNTRY(NAME)
VALUES ( /* key:1 */ 2, 'Italy')";
SQL statement:INSERT INTO country (name) VALUES ('Italy') [23505-200]
Run Code Online (Sandbox Code Playgroud)
应用程序中没有其他 sql 脚本,sql 数据也不会以编程方式加载,并且国家/地区不会被其他实体引用。该测试作为单个测试运行。
看来 INSERT 语句执行了两次,这违反了列的唯一条件。但为什么?!
当我更换时@Column(nullable = false, unique = true)一切@Column(nullable = false)正常!
有什么想法吗?解决方法?
这里的问题是关于 Spring Boot 自动配置功能的。框架将名为data.sql默认初始化程序的文件视为默认初始化程序。这里实际发生了什么:
data.sql作为初始 SQL 源执行。test(),它会尝试再次执行。data.sql@Sql有多种方法可以处理该问题:
init-data.sql)。在这种情况下,Spring 不会在应用程序上下文启动时执行它。spring.datasource.initialization-mode属性更改为never.| 归档时间: |
|
| 查看次数: |
4098 次 |
| 最近记录: |