web-dev-qa-db-ja.com

ConstraintValidatorにサービスを注入する[BeanValidator-JSR 303] Spring

こんにちは、

Bean Validator(JSR 303)内にサービスを挿入するのに問題があります。検証を実行しますが、データベースでこのレコードを検証する必要があります。

サービスを使用すると、NullPointerExceptionがスローされます。

例外:

Exception in thread "main" javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.Java:294)
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.Java:164)
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.Java:125)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.Java:86)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.Java:442)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.Java:387)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.Java:351)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.Java:303)
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.Java:133)
at net.pontoall.hemisphere.core.validation.impl.TesteValidator.main(TesteValidator.Java:25)



Caused by: Java.lang.NullPointerException
at net.pontoall.hemisphere.core.validation.impl.UsuarioValidatorImpl.doCheckLogin(UsuarioValidatorImpl.Java:48)
at net.pontoall.hemisphere.core.validation.impl.UsuarioValidatorImpl.isValid(UsuarioValidatorImpl.Java:26)
at net.pontoall.hemisphere.core.validation.impl.UsuarioValidatorImpl.isValid(UsuarioValidatorImpl.Java:1)
at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.Java:291)
... 9 more

注釈:

@Target(value = ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UsuarioValidatorImpl.class)
public @interface UsuarioValidator {

String message() default "{net.pontoall.hemisphere.validation.UsuarioValidator.message}";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}

ValidatorImpl:

public class UsuarioValidatorImpl implements ConstraintValidator<UsuarioValidator, Usuario> {

@Autowired
private IUsuarioService service;

@Override
public void initialize(UsuarioValidator arg0) {

}

@Override
public boolean isValid(Usuario entidade, ConstraintValidatorContext ctx) {
    try {
        return (this.doCheckLogin(entidade, ctx) && this.doCheckEmail(entidade, ctx));
    } catch (HemisphereException e) {
        e.printStackTrace();
        return false;
    }
}

private boolean doCheckLogin(Usuario entidade, ConstraintValidatorContext ctx) throws HemisphereException {
    ctx.buildConstraintViolationWithTemplate("{net.pontoall.hemisphere.validation.UsuarioValidator.login.message}").addConstraintViolation();

    if (entidade.getId() == null) {
        // Novo Usuário
        Usuario original = service.buscarPorLogin(entidade.getLogin());

        if (original == null) {
            return true;
        }

        return false;

    } else {

        Usuario original = service.obter(entidade.getId());
        if (original == null) {
            return true;
        } else {
            if (original.getLogin().equals(entidade.getLogin()) && original.getId().equals(entidade.getId())) {
                return true;
            }
        }

        return false;
    }
}

private boolean doCheckEmail(Usuario entidade, ConstraintValidatorContext ctx) {
    ctx.buildConstraintViolationWithTemplate("{net.pontoall.hemisphere.validation.UsuarioValidator.email.message}").addConstraintViolation();

    if (entidade.getId() == null) {
        // Novo Usuário
        Usuario original = service.buscarPorEmail(entidade.getEmail());

        if (original == null) {
            return true;
        }

        return false;

    } else {

        Usuario original = service.obter(entidade.getId());
        if (original == null) {
            return true;
        } else {
            if (original.getEmail().equals(entidade.getEmail()) && original.getId().equals(entidade.getId())) {
                return true;
            }
        }

        return false;
    }
}
}
19
Tiarê Balbi

依存性注入を介してValidator(およびValidatorFactory)インスタンスを取得できるように、Springアプリケーションコンテキストで LocalValidatorFactoryBean を設定する必要があります。

デフォルトでは、そのように取得されたバリデーターは、Pangeaが指摘しているように、制約バリデーターの実装に依存性注入サービスを提供するSpringConstraintValidatorFactoryを利用します。

12
Gunnar

依存関係をワイヤリングする場合は、 ConstraintValidatorFactory を構築するか、 SpringConstraintValidatorFactory を使用します。

2

@Pangeaが述べたように、今はカスタムConstraintValidatorFactoryを作成する必要があります。ただし、参考までに、Bean Validation 1.1ではConstraintValidatorFactoryへのインジェクションが可能です。参照 https://hibernate.onjira.com/browse/BVAL-238

1
Hardy