本文介绍了带有自定义Bean验证的休眠错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个自定义bean验证,所以我写了这个自定义约束:

I'm trying to create a custom bean validation, so I write this custom constraint:

@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..
  }

}

此外,我希望在调用某些装饰器之后立即在服务层上执行验证,因此我创建了另一个装饰器来处理此任务.

Also, I wanted the validation to be performed on the service layer just after some decorators are called, so I created an another decorator to handle this task..

@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);
      }
  }
}

一切正常,但是如果验证通过,休眠将抛出错误:

Everything works, but if validations pass, hibernate throws an error:

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值.

My entities use auto-generated id values.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;

将Widlfly 9与JEE 7结合使用.

Using Widlfly 9 with JEE 7.

推荐答案

验证执行两次,一次在服务层(我希望在其中进行),一次在实体持久/合并(jpa调用)时进行.所以我通过将这行添加到我的persistence.xml:

Validation was being executed twice, once in the service layer (where I wanted it to happen) and once when entity was persisted/merged (jpa was calling it). So I disabled it by adding this line to my persistence.xml:

<property name="javax.persistence.validation.mode" value="none"/>

现在一切正常

这篇关于带有自定义Bean验证的休眠错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 05:03
查看更多