4

I am having some UserService which makes operations on User entity. I created my own annotation and ConstraintValidator class as an implementation

I need to have that UserService injected into ConstraintValidator. And, as the spring docs says, after registering bean:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

SpringConstraingValidatorFactory is registered by default so I can easily @Autowired my service into it. (source: http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/validation.html#validation-beanvalidation-spring-constraints)

Unfortunatelly it doesnt work by me. I recieve stacktrace with NullPointerException on the field (inside class that implements ConstraintValidator):

@Autowired
private UserService userService; //here

and on the call to the service

@Override
public boolean isValid(String username, ConstraintValidatorContext constraintValidatorContext) {
    personService.doSomethingWithService(); //here
    return true;
}

So it means, that UserService is not injected properly. I have also tried to use ApplicationContextAware - implement it in my ConstraintValidator class, get the context and find the bean:

(UserService) context.getBean("userService");

But it also didnt help.. I have no idea what's wrong with my code. And finally, the stacktrace, which contains a lot of exceptions, including NullPointer and RollbackException.

java.lang.NullPointerException
    com.reportme.model.validation.UsernameAvailableValidator.isValid(UsernameAvailableValidator.java:20)
    com.reportme.model.validation.UsernameAvailableValidator.isValid(UsernameAvailableValidator.java:9)
    org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:308)
    org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:180)
    org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:124)
    org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:85)
    org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:463)
//...

org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
    org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:757)
    org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:726)
//...

javax.persistence.RollbackException: Error while committing the transaction
    org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:94)
    org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)

I use Spring 4 if its necessary and will be VERY grateful for help, thanks!

azalut
  • 4,094
  • 7
  • 33
  • 46

1 Answers1

-1

my environment is spring-boot, and below code with org.springframework.stereotype.Component annotation to my validation class is working, FYR.

@Component
public class FooValidator implements ConstraintValidator<Foo, Object> {

  @Autowired
  MyService service;

  @Override
  public void initialize(Foo constraintAnnotation) {
  }

  @Override
  public boolean isValid(Object value, ConstraintValidatorContext context) {
    return service.isValid(value);
  }
}
Yuki Yoshida
  • 1,233
  • 1
  • 15
  • 28