问题描述
我目前正在为服务中的bean验证编写一些@SpringBoottest。
@Data
@Document
public final class supplier {
@Id
@NotEmpty
private String supplierId;
...
@NotEmpty
private String hash;
....
}
测试
注释:
@ExtendWith(SpringExtension.class)
@SpringBoottest(classes = {Application.class},webEnvironment = SpringBoottest.WebEnvironment.MOCK)
和
@Test
void testValidation() {
supplier invalidsupplier = supplierTestDataUtil.createsupplier("1234");
invalidsupplier.setsupplierId(null);
//works
assertThrows(ConstraintViolationException.class,() -> supplierService.publish(invalidsupplier));
//works
assertThrows(ConstraintViolationException.class,() -> supplierService.persist(invalidsupplier));
//works not
assertThrows(ConstraintViolationException.class,() -> supplierService.saveAndPublish(invalidsupplier));
//works
assertThrows(ConstraintViolationException.class,() -> supplierService.delete(invalidsupplier));
}
服务:
@Transactional
public supplier saveAndPublish(@NotNull supplier supplier) {
supplier.setHash(messageDigester.digest(supplier));
supplier persisted = persist(supplier);
publish(supplier);
return persisted;
}
@Transactional
public supplier persist(@Valid @NotNull supplier supplier) {
return repository.save(supplier);
}
saveAndFlush上的供应商此时必须无效,因为将在该方法内生成并设置所需的哈希。 不过,我的期望是也会引发ConstraintViolationException,因为我还调用了persist和publish方法并传递了无效的文档。
我的观点是,您可以在同一类中绕过BeanValidation。
解决方法
ConstraintViolationException
将被弹簧Validator
抛出,如果您“手动”调用persist
,则不会使用该弹簧。如果从Spring上下文中调用persist
,则@Valid
批注将告诉Spring根据类的验证约束来验证对象。
您可以:
- 始终“手动”验证
hash
(无@NotEmpty
注释) - 在调用
supplier.setHash(messageDigester.digest(supplier));
之前先调用saveAndPublish
,然后将@Valid
批注添加到Supplier
的{{1}}参数中 - 将Validator实例作为字段添加到您的服务中,并在要验证的供应商上手动调用它(当然,在设置散列后使用
saveAndPublish
的情况下) - 实施两种不同类型的
saveAndPublish
,例如Supplier
(未经AddSupplier
验证;由hash
使用)和saveAndPublish
(具有{{1 }}正在验证;由EditSupplier
使用)
(这可能是不完整的列表)