1
votes

I am getting this type of error when I tried to extract data from the database. Somehow MyBatis is not recognizing my mapper xml file, which the interface mapper and xml mapper have the same file name and same directory. However, when I use this annotation it works @Select("SELECT id, client_number, name, email, health_condition FROM client.data WHERE id = #{id}") I don't want to use @Select annotation but want to use my mapper xml file instead. Does anyone have any idea to solve this problem?? I'm using Gradle(latest), Java15, and SpringBoot2.4.1

There was an unexpected error (type=Internal Server Error, status=500). Invalid bound statement (not found): nutri.api.infrastructure.datasource.client.ClientMapper.getClientById org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): nutri.api.infrastructure.datasource.client.ClientMapper.getClientById at org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:235) at org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:53) at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:115) at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:102) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85) at com.sun.proxy.$Proxy58.getClientById(Unknown Source) at nutri.api.infrastructure.datasource.client.ClientDatasource.getClientById(ClientDatasource.java:18) at nutri.api.infrastructure.datasource.client.ClientDatasource$$FastClassBySpringCGLIB$$fcc24d17.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at nutri.api.infrastructure.datasource.client.ClientDatasource$$EnhancerBySpringCGLIB$$42a63ac2.getClientById() at nutri.api.application.service.ClientService.getClientById(ClientService.java:15) at nutri.api.presentation.controller.ClientApiController.get(ClientApiController.java:20) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:832)

2
It is hard to help with that little information that you provided. Please include mapper xml file and mapper interface.Roman Konoval
@Leo The most common mistake for this error is that the XML is in src/main/java instead of src/main/resources. As there are many other possible causes for this error, the quickest way to get the answer is to share your project on GitHub. :)ave
@ave Here is my project github.com/nnakamura95/nutri/tree/developLeo
@Leo There seems to be no XML file in the repo. 🤔 It should be located in this path : nutri/nutri-api/src/main/resources/nutri/api/infrastructure/datasource/client/ClientMapper.xml.ave
The current path is nutri/nutri-api/src/main/resources/ClientMapper.xml. The correct path is nutri/nutri-api/src/main/resources/nutri/api/infrastructure/datasource/client/ClientMapper.xml. Please compare it carefully. 🔎 BTW, there seems to be several other issues (property name mismatch, missing type handler for UUID).ave

2 Answers

0
votes

For using mapper's declaration in xml file you should declare config file in the classpath (/src/main/resources)which will contain your mapper's declaration, for example mybatis-config.xml

   <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
        <settings>
<!--        <setting name="aggressiveLazyLoading" value="false"/>-->
<!--        <setting name="lazyLoadingEnabled" value="false"/>-->
<!--        <setting name="mapUnderscoreToCamelCase" value="true"/>-->
<!--        <setting name="logImpl" value="SLF4J"/>-->
<!--        <setting name="jdbcTypeForNull" value="NULL"/>-->
<!--        <setting name="callSettersOnNulls" value="true"/>-->
        </settings>
        <typeAliases>
            <!-- Data Transfer Objects -->
        </typeAliases>
    
        <typeHandlers>
    <!--        <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler"/>-->
        </typeHandlers>
    
        <!-- explicit inclusion of reusable elements -->
        <mappers>
            <mapper resource="yourMapper.xml" />
        </mappers>
    </configuration>

Besides, you should set path for the config file in your SqlSessionFactory bean, for example:

@Bean
public SqlSessionFactory sqlSessionFactory(final DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));   
    bean.setDataSource(dataSource);

    return bean.getObject();
}
0
votes

I had a similar issue and a senior developer helped me figure out, that the Clientmapper.xml file should be in a similar package as the ClientMapper java interface.

Sometimes, when we create a directory in src/main/resources as nutri.api.infrastructure.datasource.client, it creates one folder with folder name "nutri.api.infrastructure.datasource.client".

A way to go around would be to manually create this folder structure using System Explorer and just to be sure, you can also check the Project Structure>Modules and confirm that it has a hierarchical folder structure.