Search code examples
hibernatebean-validationhibernate-validator

hibernate validator - custom factory validates twice


Using a custom ConstraintValidatorFactory which is aware of the hibernate session by adding it to the configuration using following code results in double validation on any operation (create, update) this factory is responsible of.

Validator ValidBeanDatabase in this example is invoked twice with different instances. All other constraint's are validated once (@ValidBean as an example).

The implementation of the factory and validator's is similar to the one in this post:
https://community.jboss.org/wiki/AccessingTheHibernateSessionWithinAConstraintValidator

validation.xml

<constraint-validator-factory>package.SessionConstraintValidatorFactory</constraint-validator-factory>
<constraint-mapping>package/Bean-validation.xml</constraint-mapping>

Java:

final Configuration configuration = new Configuration().configure();

// get ValidatorFactory from validation.xml
final ValidatorFactory validatorFactory = Validation.byDefaultProvider().configure()
            .buildValidatorFactory();

// ... add SessionFactory to custom ConstraintValidatorFactory
((SessionConstraintValidatorFactory)validatorFactory.getConstraintValidatorFactory()).setSessionFactory(sessionFactory);

// set ValidatorFactory
configuration.getProperties().put("javax.persistence.validation.factory", validatorFactory);

Bean:

@GroupSequence(value =
{
    Bean.class, Create.class
})
@ValidBean // custom class-level constraint
public class Bean
{
    // properties and validator annotations
}

Bean-validation.xml

Adding Hibernate session aware constraint via xml mapping.

<bean class="Bean" ignore-annotations="false">
    <class>
        <constraint annotation="package.ValidBeanDatabase">
            <groups>
                <value>package.groups.Create</value>
            </groups>
        </constraint>
    </class>
</bean>

Edit:

Hibernate-Configuration

<property name="javax.persistence.validation.group.pre-persist">
    javax.validation.groups.Default, package.groups.Create
</property>

Glassfish 3.1.2 with Hibernate Validator 4.2

@Gunner Do you have any validation-related configuration in other places, e.g. persistence.xml? No


Solution

  • The constraint is validated twice because you specify two groups for validation upon pre-persist in your file "Hibernate-Configuration" , Default and Create.

    The constraint is part of the Create group as per your XML mapping, while the default group sequence of type Bean also contains this group (as per the @GroupSequence annotation on Bean). The constraint is therefore validated twice, once as part of the default group and once as part of the Create group.

    So you either validate only one group upon pre-persist or you change the default group sequence of the Bean type.