I am using Spring MVC with Spring-Mybatis for performing basic CRUD operations using Annotations(@Insert
, @Select
etc) and getting this following exception
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
Here's a related question, mybatis spring mvc application, getting Invalid bound statement (not found) but that doesn't solve my problem as it uses XML(UserMapper.xml
) mapping for queries where I use java interfaces(UserMapper.java
) with Annotations.
Exception stacktrace:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.spring.mybatisdemo.mappers.UserMapper.selectNationality
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:801)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.__doHandle(ContextHandler.java:1126)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1060)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:113)
at org.eclipse.jetty.server.Server.handle(Server.java:509)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:288)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:240)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:539)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:540)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.spring.mybatisdemo.mappers.UserMapper.selectNationality
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:196)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:44)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:59)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
at com.sun.proxy.$Proxy41.selectNationality(Unknown Source)
at com.spring.mybatisdemo.service.UserServiceImpl.selectNationalityById(UserServiceImpl.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.zeroturnaround.javarebel.fY.invoke(JRebel:1114)
at java.lang.reflect.Method.invoke(Method.java)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy43.selectNationalityById(Unknown Source)
at com.spring.mybatisdemo.controller.UserController.getUsers(UserController.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
springConfig.xml
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="com.spring.mybatisdemo.model"/>
<property name="mapperLocations" value="classpath*:com/spring/mybatis/mappers/*.xml" />
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.spring.mybatisdemo.mappers" />
</bean>
Nationality POJO class,
public class Nationality {
private Long nationalityId;
private String name;
//ignoring getters and setters
}
I'm using annotation for the queries and below is my relevant code from UserMapper.java interface,
@Select("SELECT nationalityId, name FROM nationality where nationalityId = #{nationalityId} ")
public Nationality selectNationality(Long nationalityId);
Calling the above method like,
Nationality nationality = userService.selectNationalityById(new Long("1"));
And in UserServiceImpl.java
I have injected the UserMapper bean and use it like,
userMapper.selectNationality(nationalityId);
The same query I used for selecting the teamById
work fine,
userMapper.getTeamById(teamId)
and
@Select("SELECT teamId, name FROM TEAM WHERE teamId = #{teamId}")
public Team getTeamById(Long teamId);
and the corresponding teamById query in console,
[artifact:mvn] 2015-11-02 18:51:20 DEBUG SpringManagedTransaction:54 - JDBC Connection [com.mysql.jdbc.JDBC4Connection@1e846b60] will be managed by Spring
[artifact:mvn] 2015-11-02 18:51:20 DEBUG getTeamById:54 - ==> Preparing: SELECT teamId, name FROM TEAM WHERE teamId = ?
[artifact:mvn] 2015-11-02 18:51:20 DEBUG getTeamById:54 - ==> Parameters: 4(Long)
[artifact:mvn] 2015-11-02 18:51:20 DEBUG getTeamById:54 - <== Total: 1
I can't get why only the Nationality has this problem while the same method for Team class works fine. What could be the problem in my code for fetching the Nationality data?
I once made a similar mistake which turned out that the directories were incorrect.
If the UserMapper's namespace is com.mybatisdemo.mappers.UserMapper
, make sure mapper-locations is src/resources/com/mybatisdemo/mappers/
.
Sometimes we might create a directory named com.mybatisdemo.mappers
, then its location turns out to be src/resources/com.mybatisdemo.mappers
which is wrong.