0

I have tried to create a custom annotation with a constraint validator in the spring boot framework and I'm getting an error of injected services being null when executing the custom validator.

And, I have checked with the previous answers related to this. But, any answer didn't work for me now.

Some of them are as follows,

javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator

Autowired gives Null value in Custom Constraint validator

http://dolszewski.com/spring/custom-validation-annotation-in-spring/

My custom annotation and constraint validator as follows,

Custom Annotation

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Constraint(validatedBy = UniqueFoodNameValidator.class)
public @interface UniqueFoodName {
    String message() default "{UniqueFoodName}";

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

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

Custom Constraint Validator

public class UniqueFoodNameValidator implements ConstraintValidator<UniqueFoodName, String> {

    private FoodService foodService;

    @Autowired
    public UniqueFoodNameValidator(FoodService foodService) {
        this.foodService = foodService;
    }

    @Override
    public void initialize(UniqueFoodName constraintAnnotation) {

    }

    @Override
    public boolean isValid(String foodName, ConstraintValidatorContext context) {
        return Objects.isNull(foodName) || foodService.get(foodName).isEmpty();
    }
}

So, I would really appreciate If someone cloud help me to figure out the issue and to resolve this.

Note that: FoodService is an interface and it's methods implemented in the FoodServiceImpl class.

Amesh Jayaweera
  • 216
  • 2
  • 11

1 Answers1

0

A bit late answer, but hope it will be useful for someone.

I suppose the problem is in your Hibernate configuration. The thing is that you validate the field twice. It happens because both Spring and Hibernate run validation automatically.

If you debug isValid method, you will see the flow runs into the method twice first time your FoodService will be injected, but not the second time.

To fix it you can disable Hibernate auto validation. For example:

private Properties hibernateSettings() {
    Properties settings = new Properties();

    // some settings

    settings.put("javax.persistence.validation.mode", "none");
    return settings;
}

@Bean
public LocalSessionFactoryBean getSessionFactory() {
    LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
    sessionFactoryBean.setDataSource(dataSource());
    sessionFactoryBean.setHibernateProperties(hibernateSettings());
    sessionFactoryBean.setPackagesToScan("com.springmvc.models");
    return sessionFactoryBean;
}
idelkaro
  • 37
  • 4