我尝试创建自定义bean验证,因此我编写了这个自定义约束:
@Documented
@Constraint(validatedBy = ValidPackageSizeValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPackageSize {
String message() default "{br.com.barracuda.constraints.ValidPackageSize}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
验证员:
public class ValidPackageSizeValidator implements ConstraintValidator<ValidPackageSize, PackageSize> {
...
@Override
public boolean isValid(PackageSize value, ConstraintValidatorContext context) {
...validation login here..
}
}
另外,我希望在调用一些装饰器之后在服务层上执行验证,所以我创建了另一个装饰器来处理这个任务。
@Decorator
public abstract class ConstraintsViolationHandlerDecorator<T extends AbstractBaseEntity> implements CrudService<T> {
@Any
@Inject
@Delegate
CrudService<T> delegate;
@Inject
Validator validator;
@Override
@Transactional
public T save(T entity) {
triggerValidations(entity);
return delegate.save(entity);
}
private void triggerValidations(T entity) {
List<String> errorMessages = validator.validate(entity).stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toList());
if (!errorMessages.isEmpty()) {
throw new AppConstraintViolationException(errorMessages);
}
}
}
一切正常,但如果验证通过,则hibernate会抛出错误:
ERROR [default task-6] (AssertionFailure.java:50) - HHH000099: an assertion failure occurred (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in br.com.barracuda.model.entities.impl.PackageSize entry (don't flush the Session after an exception occurs)
我的实体使用自动生成的id
值。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
将Widlfly 9与JEE 7一起使用。
答案 0 :(得分:1)
验证正在执行两次,一次在服务层(我希望它发生)和一次实体被持久化/合并(jpa正在调用它)。所以我通过将此行添加到persistence.xml
:
<property name="javax.persistence.validation.mode" value="none"/>
现在一切正常