这是我的实体:
@Builder
@Data
@Entity
@Table(name = "audit_log")
public class AuditEventEntity {
@Id
@GeneratedValue
private UUID id;
private long createdEpoch;
@NotNull
@Size(min = 1, max = 128)
private String label;
@NotNull
@Size(min = 1)
private String description;
}
这是我的存储库:
@Repository
public interface AuditEventRepository extends PagingAndSortingRepository<AuditEventEntity, UUID> {
}
当我为存储库编写以下单元测试时,即使“ label”字段为空,保存也会成功!
@DataJpaTest
@RunWith(SpringRunner.class)
public class AuditRepositoryTest {
@Test
public void shouldHaveLabel() {
AuditEventEntity entity = AuditEventEntity.builder()
.createdEpoch(Instant.now().toEpochMilli())
.description(RandomStringUtils.random(1000))
.build();
assertThat(entity.getLabel()).isNullOrEmpty();
AuditEventEntity saved = repository.save(entity);
// Entity saved and didn't get validated!
assertThat(saved.getLabel()).isNotNull();
// The label field is still null, and the entity did persist.
}
@Autowired
private AuditEventRepository repository;
}
无论我使用@NotNull
还是@Column(nullable = false)
,都使用列上的not null
标志创建数据库:
Hibernate: create table audit_log (id binary not null, created_epoch bigint not null, description varchar(255) not null, label varchar(128) not null, primary key (id))
我认为验证器将自动运行。我在这里做什么错了?
答案 0 :(得分:3)
我认为验证器将自动运行。我在做什么 这里错了吗?
您保存了实体,但没有刷新当前实体管理器的状态。
因此,尚未执行实体的验证。
您可以参考Hibernate validator FAQ:
为什么我在调用persist()时未验证我的JPA实体?
为什么我在致电
persist()
时未验证我的JPA实体?短 如果您希望验证通过,请致电EntityManager#flush()
触发。休眠ORM和其他一些ORM尝试批处理尽可能多的操作 访问数据库时可能出现的情况。实际的 实体“持续”操作仅在您调用
flush()
或当 交易提交。此外,知道哪个实体将要保留取决于您 级联策略和对象图的状态。冲洗是什么时候 Hibernate ORM标识所有已更改的实体,并 需要数据库操作(另请参见HHH-8028)。
因此,使用JpaRepository.saveAndFlush()
代替JpaRepository.save()
来验证实体。
或者,在测试类中插入EntityManager
或TestEntityManager
,调用JpaRepository.save()
,然后调用EntityManager/TestEntityManager.flush()
。
有关信息:
JpaRepository.save()
调用em.persist(entity)
/ em.merge(entity)
JpaRepository.saveAndFlush()
先调用JpaRepository.save()
,然后再调用em.flush()
要能够调用saveAndFlush()
,必须使您的Repository接口扩展JpaRepository
,例如:
public interface AuditEventRepository extends JpaRepository<AuditEventEntity, UUID> {
随着JpaRepository
扩展PagingAndSortingRepository
,此更改与您现有的声明保持一致。
我要补充一点,这个断言不是必需的:
assertThat(saved.getLabel()).isNotNull();
您要声明的是抛出了ValidationException
,并且可能包含实际的错误消息。