Spring Boot测试中@notnull校验未触发,预期异常未抛出
解决@NotNull约束未触发DataIntegrityViolationException的问题
以下是关键排查和修复步骤:
1. 确保数据库层面生成NOT NULL约束
Hibernate默认会根据实体类的@NotNull注解生成数据库字段的NOT NULL约束,但需配置正确的DDL模式。在测试环境配置文件(如application-test.yml)中设置:
spring: jpa: hibernate: ddl-auto: create-drop
该配置会在测试启动时重建表结构,保证约束被正确生成。
2. 触发Hibernate立即执行SQL
save()方法仅将实体加入持久化上下文,不会立即发送SQL到数据库,因此无法触发数据库约束检查。需改用saveAndFlush()强制立即执行:
修改测试代码:
@Test public void expect_save_cameraWithNullName_throwsException() { // arrange camera.setCameraName(null); // act and assert Assertions.assertThatThrownBy(() -> cameraRepository.saveAndFlush(camera) ).isInstanceOf(DataIntegrityViolationException.class); }
3. 移除测试方法上的@Transactional(可选)
测试方法上的@Transactional默认会在测试结束后回滚事务,即使调用saveAndFlush(),部分场景下数据库约束检查可能被延迟到提交阶段。移除该注解后,操作会在默认事务中执行并自动提交,确保约束触发。
4. 开启JPA Bean Validation(可选)
如果希望在持久化前触发Bean Validation的@NotNull校验(而非仅依赖数据库约束),需开启JPA校验模式:
在配置文件中添加:
spring: jpa: properties: javax.persistence.validation.mode: auto
此时Hibernate会在持久化前自动校验实体,抛出ConstraintViolationException,可根据需求选择捕获该异常或数据库层面的DataIntegrityViolationException。
内容的提问来源于stack exchange,提问作者Selahattin
相关产品推荐
相关产品推荐

