title: IllegalArgumentException: Type cannot be null
body: <p>I am confronting with an issue and it seems that many people encountered it and probably couldn't solve it.</p>
  
  <p>I have the following MYSQL stored procedure. This is just a sample to see if everything works fine, then I would've start adding parameters like <code>inactive</code>.</p>
  
  <pre><code>CREATE DEFINER=`root`@`localhost` PROCEDURE `get_resource_types`()
  BEGIN
      SELECT *
      FROM resource_types
      WHERE inactive = 0;
  END
  </code></pre>
  
  <p>The entity which maps the <code>resource_types</code> table and the named stored procedure query.</p>
  
  <pre><code>@NamedStoredProcedureQuery(
          name="getResourceTypes",
          procedureName="get_resource_types",
          resultClasses = ResourceType.class,
          parameters = {}
  )
  @Entity
  @Table(name = "resource_types")
  public class ResourceType {
      ... fields with annotations used for validation + getters and setters ...
  }
  </code></pre>
  
  <p>And here is my <code>JpaRepository</code> from which I make the call to the stored procedure</p>
  
  <pre><code>@Repository
  public interface ResourceTypeRepository extends JpaRepository&lt;ResourceType, Long&gt; {
      @Procedure("ResourceType.getResourceTypes")
      List&lt;ResourceType&gt; getResourceTypes();
  
  }
  </code></pre>
  
  <p>The <code>getAll()</code> method which resides in a <code>@Service</code></p>
  
  <pre><code>public List&lt;ResourceType&gt; getAll(){
      final List&lt;ResourceType&gt; resourceTypes = resourceTypeRepository.getResourceTypes();
      return resourceTypes;
  }
  </code></pre>
  
  <p>When I try to run this I get the following stack trace:</p>
  
  <pre><code>org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
      at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
      at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
      at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
      at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
      at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:144)
      at com.test.ihbs.controller.ResourceTypeControllerTest.test_getAll(ResourceTypeControllerTest.java:111)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
      at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
      at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
      at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
      at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
      at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
      at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
      at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
      at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
      at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
      at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
      at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
      at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Type cannot be null; nested exception is java.lang.IllegalArgumentException: Type cannot be null
      at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
      at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
      at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
      at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
      at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:122)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
      at com.sun.proxy.$Proxy87.getResourceTypes(Unknown Source)
      at com.ihbs.service.ResourceTypeService.getAll(ResourceTypeService.java:34)
      at com.ihbs.controller.ResourceTypeController.getAllResourceTypes(ResourceTypeController.java:44)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:497)
      at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
      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:966)
      ... 58 more
  Caused by: java.lang.IllegalArgumentException: Type cannot be null
      at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.setHibernateType(AbstractParameterRegistrationImpl.java:182)
      at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.&lt;init&gt;(AbstractParameterRegistrationImpl.java:131)
      at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.&lt;init&gt;(AbstractParameterRegistrationImpl.java:140)
      at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.&lt;init&gt;(AbstractParameterRegistrationImpl.java:77)
      at org.hibernate.procedure.internal.PositionalParameterRegistration.&lt;init&gt;(PositionalParameterRegistration.java:41)
      at org.hibernate.procedure.internal.ProcedureCallImpl.registerParameter(ProcedureCallImpl.java:275)
      at org.hibernate.jpa.internal.StoredProcedureQueryImpl.registerStoredProcedureParameter(StoredProcedureQueryImpl.java:128)
      at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.newAdhocStoredProcedureQuery(StoredProcedureJpaQuery.java:147)
      at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.createStoredProcedure(StoredProcedureJpaQuery.java:110)
      at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.doCreateQuery(StoredProcedureJpaQuery.java:68)
      at org.springframework.data.jpa.repository.query.StoredProcedureJpaQuery.createQuery(StoredProcedureJpaQuery.java:58)
      at org.springframework.data.jpa.repository.query.JpaQueryExecution$ProcedureExecution.doExecute(JpaQueryExecution.java:295)
      at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:74)
      at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:97)
      at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:88)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:395)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:373)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.data.repository.core.support.RepositoryFactorySupport$DefaultMethodInvokingMethodInterceptor.invoke(RepositoryFactorySupport.java:486)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
      ... 80 more
  </code></pre>
  
  <p>Any ideas why is this happening and how to fix it?</p>
  
  <p>The documentation for <code>InvalidDataAccessApiUsageException</code> says:</p>
  
  <blockquote>
    <p>Exception thrown on incorrect usage of the API, such as failing to
    "compile" a query object that needed compilation before execution.
    This represents a problem in our Java data access framework, not the
    underlying data access infrastructure.</p>
  </blockquote>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>If I change the repository into the following code, it will work, which means there are issues with name procedure query. I still need to make the stored procedure way to work. </p>
  
  <pre><code>@Repository
  public interface ResourceTypeRepository extends JpaRepository&lt;ResourceType, Long&gt; {
  
      @Query("SELECT rt FROM ResourceType rt WHERE rt.inactive = 0")
      List&lt;ResourceType&gt; getResourceTypes();
  
  }
  </code></pre>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>I am not using EclipseLink (or at least I don't know about his existence)</p>
  
  <p><strong>UPDATE 3</strong></p>
  
  <p>I could not found the cause of this problem even if I went through the code, debugging. But I found something that may help in finding the issue.</p>
  
  <p>I found this piece of code in <code>org/springframework/data/jpa/repository/query/StoredProcedureJpaQuery.java</code> and if you may notice that on the last line there is a call to a function where it gets the total number of parameters and adds an extra one. Here may be the problem, the extra parameter. Still, this may not be the issue because I suppose it can follow another path under different circumstances.</p>
  
  <pre><code>/**
   * Extracts the output value from the given {@link StoredProcedureQuery}.
   * 
   * @param storedProcedureQuery must not be {@literal null}.
   * @return
   */
  Object extractOutputValue(StoredProcedureQuery storedProcedureQuery) {
  
      Assert.notNull(storedProcedureQuery, "StoredProcedureQuery must not be null!");
  
      if (!procedureAttributes.hasReturnValue()) {
          return null;
      }
  
      if (StringUtils.hasText(procedureAttributes.getOutputParameterName())) {
          return storedProcedureQuery.getOutputParameterValue(procedureAttributes.getOutputParameterName());
      }
  
      return storedProcedureQuery.getOutputParameterValue(getQueryMethod().getParameters().getNumberOfParameters() + 1);
  }
  </code></pre>