【bug记录】“openfeign“ 报错Invalid bound statement (not found)

问题背景

springcloud整合openfeign,两个服务之间的远程调用。正常启动服务,访问测试接口时,总是报错:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.wut.config.UserSrvFeignClient.findUserByUserId

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.wut.config.UserSrvFeignClient.findUserByUserId
	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:227) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:49) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65) ~[mybatis-3.4.6.jar:3.4.6]
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58) ~[mybatis-3.4.6.jar:3.4.6]
	at com.sun.proxy.$Proxy85.findUserByUserId(Unknown Source) ~[na:na]
	at com.wut.service.ContentService.findShareContent(ContentService.java:35) ~[classes/:na]
	at com.wut.controller.ContentController.getShareContent(ContentController.java:18) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.37.jar:4.0.FR]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.37.jar:9.0.37]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.37.jar:9.0.37]
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.37.jar:9.0.37]

原因及解决方案

产生了重复扫描的问题。由于两个服务使用的是同一个包:com.wut,在启动类中添加@MapperScan注解时,均为@MapperScan("com.wut")。这样导致不同的服务的Mapper文件被重复扫描。

主要原因:相同的MapperScan使得对应路径下的mapper文件只扫描以便,会使另一个mapper文件无法完成映射,就会导致数据库错误,无法完成feign远程调用。【深度原因还需进一步分析】

修改方法:将不同服务的MapperScan注解中的路径进行区分即可,我按照服务名称进行了区分,问题得到解决。修正后两个MapperScan如下:

@MapperScan("com.wut.content.dao")
@MapperScan("com.wut.user.dao")

### 解决方案 `org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)` 是 MyBatis 中常见的异常之一,通常表示框架无法找到指定的 Mapper 方法与其对应的 SQL 语句之间的映射关系。以下是可能的原因以及解决方案: #### 可能原因及解决办法 1. **Mapper 接口未被正确扫描** 如果 `JobMapper` 接口所在的包路径未被 Spring 或其他容器正确扫描到,则可能导致该接口不可用。确保在配置文件中已声明正确的包路径以便自动扫描所有 Mapper 接口[^2]。 配置示例(Spring Boot): ```java @MapperScan("com.example.mapper") // 替换为实际的包名 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 2. **XML 文件命名不匹配** 当使用 XML 定义 SQL 映射时,如果 XML 文件名称与 Mapper 接口名称不同步,也会引发此问题。例如,对于 `JobMapper.java`,其对应的 XML 应命名为 `JobMapper.xml` 并放置在同一目录下[^5]。 3. **SQL ID 不一致** 确认 `insertJob` 方法定义中的注解或 XML 中的 `<insert>` 节点是否具有相同的 ID 名称。任何拼写错误都会导致绑定失败[^3]。 示例代码片段: ```xml <!-- JobMapper.xml --> <mapper namespace="com.example.mapper.JobMapper"> <insert id="insertJob" parameterType="Job"> INSERT INTO job (name, description) VALUES (#{name}, #{description}) </insert> </mapper> ``` 4. **Mapper 注册缺失** 若手动注册 Mapper,则需确认已在 MyBatis 配置类中显式加载了相应的 Mapper 类或 XML 文件[^4]。 示例代码片段: ```java @Configuration public class MyBatisConfig { @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); sessionFactory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); return sessionFactory.getObject(); } } ``` 5. **MyBatis Plus 特殊场景** 使用 MyBatis-Plus 时,某些自动生成的功能可能会覆盖默认行为。因此,在扩展方法上应特别注意是否遵循约定俗成的规则或者提供了额外的支持。 --- ### 总结 通过上述分析可以发现,“Invalid bound statement (not found)” 错误主要源于以下几个方面:Mapper 扫描范围设置不当、资源文件关联失误、函数签名不符或是框架集成过程中遗漏必要步骤等问题所致。逐一排查以上提到的因素即可定位并修复此类 Bug。 ```python def check_mapper_binding(): """ A function to simulate checking mapper binding issues. This is a conceptual representation and not actual code execution. """ pass ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值