不能在ConstraintValidator中使用@Autowired - 给出NPE

时间:2014-09-11 18:27:44

标签: java spring hibernate-validator spring-validator

我有一个自定义的ConstraintValidator来验证@TelephoneNumber注释,如下所示:

@Component
public class TelephoneNumberValidator implements ConstraintValidator<TelephoneNumber, String> {

    @Autowired
    ValidationHelper validationHelper;

    @Override
    public void initialize(TelephoneNumber telephoneNumber) { }

    @Override
    public boolean isValid(String telephoneNumber, ConstraintValidatorContext cxt) {

        if(telephoneNumber == null) {
            return true;
        } else {
            return validationHelper.isTelephoneNumber(telephoneNumber);
        }
    }
}

如您所见,它会自动装配一个ValidationHelper对象,该对象标记为@Component

在我的@Repository内,每当我通过sessionFactory.getCurrentSession().persist(myobject);保留我的对象时,我得到一个NPE,validationHelper为空。

我的hibernate配置是:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages="uk.co.domain.repositories")
public class HibernateConfig {

    static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
    static final String URL = "jdbc:mysql://localhost:3306/mydatabase";
    static final String USERNAME = "user";
    static final String PASSWORD = "pass";

    @Bean
    public DataSource dataSource() {

        BasicDataSource dataSource = new org.apache.commons.dbcp2.BasicDataSource();
        dataSource.setDriverClassName(DRIVER_CLASS);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);
        dataSource.setUrl(URL);
        dataSource.setInitialSize(10);

        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {

        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "uk.co.domain.models" });

        return sessionFactory;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {

        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory().getObject());

        return txManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {

        return new PersistenceExceptionTranslationPostProcessor();
    }
}

我已按如下方式配置LocalValidatorFactoryBean

@Configuration
@ComponentScan(basePackages="uk.co.domain.validators")
public class ValidatorConfig {

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
        return methodValidationPostProcessor;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        return localValidatorFactoryBean;
    }
}

然而,这并没有解决问题。 MVC表单验证工作得非常好,只是Hibernate持久化操作失败了。

我是否需要告诉Hibernate使用此验证器?我会很感激任何指针。

1 个答案:

答案 0 :(得分:0)

正在使用的验证程序实例可能不是Spring管理的bean。我怀疑Hibernate正在创建验证器的实例并使用该实例而不是您在Spring中创建的实例。

您需要让Hibernate使用Spring托管实例或找到解决方法(在验证器中自己实例化)。考虑使用静态方法 - 当我验证电话号码时,验证方法通常不需要进行任何数据库调用或任何需要大量依赖注入的事情。