How to write a custom ConstraintValidatorFactory

A common use for a custom ConstraintValidatorFactory is the need to inject resources (eg the EntityManager or the Hibernate Session) into your custom ConstraintValidators. Here is what you have to do:

 

  • First you have to write your custom implementation of ConstraintValidatorFactory. This implementation can for example make use of Spring's ApplicationContext in order to implement dependency injecton for ConstraintValidator creation.
  • Next you have to tell Bean Validation to use your custom factory. There are several ways of doing this
    • Add validation.xml to the root of your classpath specifying your custom factory
      <?xml version="1.0" encoding="UTF-8"?>
      <validation-config
              xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd">
          <constraint-validator-factory>
              org.hibernate.jsr303.tck.tests.xmlconfiguration.XmlDefinedConstraintValidatorFactory
          </constraint-validator-factory>
      </validation-config>
    • In the case of JPA 2 you can pass the ValidatorFactory instance via the map passed as an argument to the Persistence.createEntityManagerFactory call. The map key used must be the standard property name javax.persistence.validation.factory. The factory itself can be built using the boostrapping API of Bean Validation (in the case of Hibernate the factory will be passed down to Ejb3Configuration)

 

Note, in case you are trying to access the Hibernate Session or EntityManager within the ConstraintValidator you have to make sure to open a new session.

 

See also: HV-246, HV-230