title: How do get around a javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator: in Spring
body: <p>Anyone ever worked with spring-boot and run into this error.</p>
  
  <pre><code>javax.validation.ValidationException: HV000064: Unable to instantiate ConstraintValidator:
  **&lt;more stack...&gt;**
  Caused by: java.lang.NoSuchMethodException: 
  com.comapany.package.validator.&lt;init&gt;()
  </code></pre>
  
  <p><a href="https://docs.jboss.org/hibernate/validator/6.1/reference/en-US/html_single/#_code_constraintvalidatorfactory_code" rel="nofollow noreferrer">I know it has something to do with this</a>:</p>
  
  <blockquote>
    <p>Any constraint implementations relying on ConstraintValidatorFactory
    behaviors specific to an implementation (dependency injection, no
    no-arg constructor and so on) are not considered portable.</p>
  </blockquote>
  
  <p>but my Validator cannot be portable because it requires the repo to work so that is not an option.</p>
  
  <p>I have tried adding a no-args constructor to my validator but then i get this:</p>
  
  <pre><code>javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
  Caused by: java.lang.NullPointerException
  </code></pre>
  
  <p>I have also tried to override the LocalValidatorFactoryBean:</p>
  
  <pre><code>@Bean
  public LocalValidatorFactoryBean localValidatorFactoryBean(ConstraintValidatorFactory validatorFactory) {
          var bean = new LocalValidatorFactoryBean();
          bean.setConstraintValidatorFactory(validatorFactory);
          return bean;
      }
  </code></pre>
  
  <p>and even though Spring recognizes my factory, I still get that error(HV000064).</p>
  
  <p>Another option would be to add a concrete Repo in my no-args constructor for my validator, but that feels wrong.</p>
  
  <pre><code>public Validator(){
      repo = new ConcreteClassOfRepository();
  }
  </code></pre>
  
  <p>So how do I proceed?</p>
  
  <p>EDIT (reuested code):</p>
  
  <blockquote>
    <p>ValidatorCode</p>
  </blockquote>
  
  <pre><code>@Service
  @AllArgsConstructor
  @NoArgsConstructor
  public class UniqueIdValidator implements ConstraintValidator&lt;UniqueId, String&gt; {
  
      @Autowired
      private SampleRepository repo;
  
  
      @Override
      public void initialize(UniqueId constraintAnnotation) {
  
      }
  
      @Override
      public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
          return !repo.existsById(s);
      }
  
  }
  </code></pre>
  
  <blockquote>
    <p>StackTrace</p>
  </blockquote>
  
  <pre><code>javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
  
      at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:177)
      at org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(SimpleConstraintTree.java:68)
      at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:73)
      at org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:127)
      at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:120)
      at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:552)
      at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:515)
      at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:485)
      at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:447)
      at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:397)
      at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:173)
      at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:116)
      at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:80)
      at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:211)
      at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:84)
      at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
      at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
      at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
      at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
      at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
      at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:57)
      at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:108)
      at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1309)
      at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1389)
      at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1558)
      at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1526)
      at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1574)
      at org.springframework.data.jpa.repository.support.SimpleJpaRepository.existsById(SimpleJpaRepository.java:327)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:567)
      at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:371)
      at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:204)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:657)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:621)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
      at com.sun.proxy.$Proxy112.existsById(Unknown Source)
      at com.packageName.ValidationTest.trackingBugCausedByValidatorNotPortable(ValidationTest.java:99)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.base/java.lang.reflect.Method.invoke(Method.java:567)
      at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
      at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
      at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
      at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
      at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
      at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
      at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
      at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
      at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
      at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
      at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
      at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
      at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
      at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
      at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
      at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
      at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
      at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
      at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
      at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
  Caused by: java.lang.NullPointerException
      at com.packageName.UniqueIdValidator.isValid(UniqueIdValidator.java:27)
      at com.packageName.UniqueIdValidator.isValid(UniqueIdValidator.java:11)
      at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateSingleConstraint(ConstraintTree.java:171)
  </code></pre>
  
  <blockquote>
    <p>SampleRepository</p>
  </blockquote>
  
  <pre><code>@Repository
  public interface SampleRepository extends JpaRepository&lt;SampleEntity, String&gt; {
  
  }
  </code></pre>
  
  <blockquote>
    <p>Tracking Test</p>
  </blockquote>
  
  <pre><code>    @Test
      void trackingBugCausedByValidatorNotPortable() {
          var entity = new SampleEntity();
          entity.setId("an id");
          repo.save(entity);
          repo.delete(entity);
          assertTrue(repo.existsById("an id"));
          fail("Add @UniqueId to SampleEntity and run");
      }
  </code></pre>
  
  <p><code>repo.save()</code> is successful, 
  <code>repo.delete()</code> is successful, 
  but <code>repo.existsById()</code> breaks with the aforementioned exception</p>
  
  <blockquote>
    <p>CustomConstraintValidatorFactory &amp; ImplementationFactory </p>
  </blockquote>
  
  <pre><code>public class CustomConstraintValidatorFactory implements ConstraintValidatorFactory {
  
      private final ConstraintValidatorFactory defaultFactory;
      private final ImplementationFactory[] implementations;
  
      public CustomConstraintValidatorFactory(ConstraintValidatorFactory defaultFactory, ImplementationFactory... implementations) {
          this.defaultFactory = defaultFactory;
          this.implementations = implementations;
      }
  
      @Override
      public &lt;T extends ConstraintValidator&lt;?, ?&gt;&gt; T getInstance(Class&lt;T&gt; key) {
          return Arrays.stream(implementations)
              .filter(factory -&gt; factory.supports(key))
              .findFirst()
              .map(ImplementationFactory::create)
              .map(v -&gt; (T) v)
              .orElseGet(() -&gt; defaultFactory.getInstance(key));
      }
  
      @Override
      public void releaseInstance(ConstraintValidator&lt;?, ?&gt; instance) {
      }
  }
  
  public class InheritanceMatchValidatorFactory implements ImplementationFactory {
  
      Class klass;
      Supplier&lt;ConstraintValidator&gt; validator;
  
      @Override
      public boolean supports(Class key) {
          return klass.isAssignableFrom(key);
      }
  
      @Override
      public ConstraintValidator&lt;?, ?&gt; create() {
          return validator.get();
      }
  
  }
  </code></pre>