Creating custom unique constraints
<p>I Defined my @FuSsA_UniqueKey constraint annotation:</p>

<pre><code>package com.fussa.employee.util;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Constraint(validatedBy = { UniqueIDValidator.class })
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface FuSsA_UniqueKey {

    String columnNames();

    String message() default "{Value is not unique}";

    Class&lt;?&gt;[]groups() default {};

    Class&lt;? extends Payload&gt;[]payload() default {};

}
</code></pre>

<p>Having defined my annotation, i created a constraint validator <strong>UniqueIDValidator</strong>, which is able to validate elements with a <strong>@FuSsA_UniqueKey</strong> annotation:</p>

<pre><code>   package com.fussa.employee.util;

import java.io.Serializable;
import java.util.List;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder;
import javax.validation.ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderDefinedContext;

import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

public class UniqueIDValidator implements ConstraintValidator&lt;FuSsA_UniqueKey, Serializable&gt; {

    @Autowired
    private SessionFactory sessionFactory;

    private Session s;

    private String uniqueField;
    private FuSsA_UniqueKey unique;

    public void initialize(FuSsA_UniqueKey unique) {
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        uniqueField = unique.columnNames();
    }

    @Override
    public boolean isValid(Serializable arg0, ConstraintValidatorContext arg1) {
        String a = arg0.getClass().getSimpleName();
        String query = String.format("from %s where %s = :%s ", a, uniqueField, uniqueField);
        List&lt;?&gt; list = null;
        try {
            s = sessionFactory.getCurrentSession();
            s.setFlushMode(FlushMode.COMMIT);
            list = s.createQuery(query).setParameter(uniqueField, "FuSsA").list();

        } catch (HibernateException e) {
            s = sessionFactory.openSession();
            s.setFlushMode(FlushMode.COMMIT);
            list = s.createQuery(query).setParameter(uniqueField, "FuSsA").list();
        } finally {
            // this is to reset the hibernate config I think
            s.setFlushMode(FlushMode.AUTO);
        }
        if (list != null &amp;&amp; !(list.size() &gt; 1)) {
            return true;
        } else {
            ConstraintViolationBuilder cvb = arg1.buildConstraintViolationWithTemplate(unique.message());
            NodeBuilderDefinedContext nbdc = cvb.addNode(unique.columnNames());
            ConstraintValidatorContext cvc = nbdc.addConstraintViolation();
            cvc.disableDefaultConstraintViolation();
            return false;
        }
    }
}
</code></pre>

<p>methode <strong>saveEmployee</strong> on my <strong>Controller</strong>:</p>

<pre><code>    @Autowired
    EmployeeService service;

    @Autowired
    MessageSource messageSource;
    @Autowired
    private Validator validator;

  @RequestMapping(value = { "/new" }, method = RequestMethod.POST)
    public String saveEmployee(@Valid Employee employee, BindingResult result, ModelMap model) {

        if (result.hasErrors()) {
            return "registration";
        }

        Set&lt;ConstraintViolation&lt;Employee&gt;&gt; violations = validator.validate(employee);

        if (!violations.isEmpty()) {

            FieldError ssnError = new FieldError("employee", "ssn", messageSource.getMessage("non.unique.ssn",
                    new String[] { employee.getSsn() }, Locale.getDefault()));
            result.addError(ssnError);

            return "registration";
        } else {
            service.saveEmployee(employee);

            model.addAttribute("success", "Employee " + employee.getName() + " registered successfully");
            return "success";
        }
    }
</code></pre>

<h2>Edit</h2>

<p>i also add to my <strong>@Configuration</strong> class <strong>AppConfig</strong> this methode, so i can autowired it on my controller "not sure if its correct":</p>

<pre><code>@Bean
    public Validator localValidatorFactoryBean() {
        return new LocalValidatorFactoryBean();
    }
</code></pre>

<p>when i try to save my object .. i got this errors:</p>

<pre><code>Caused by: javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:451)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:127)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:87)
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:73)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:592)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:555)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:490)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:454)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:406)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:204)
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:108)
    at org.springframework.validation.DataBinder.validate(DataBinder.java:866)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.validateIfApplicable(ModelAttributeMethodProcessor.java:164)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:111)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
    ... 31 more
Caused by: java.lang.NullPointerException
    at com.fussa.employee.util.UniqueIDValidator.isValid(UniqueIDValidator.java:54)
    at com.fussa.employee.util.UniqueIDValidator.isValid(UniqueIDValidator.java:1)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:448)
    ... 54 more
</code></pre>

<p>so the error is catched on that line :</p>

<pre><code>ConstraintViolationBuilder cvb = arg1.buildConstraintViolationWithTemplate(unique.message());
</code></pre>

<p>thanks for any advices..</p>