当前位置: 首页 > news >正文

Springboot集成Mybatis在不同文件夹下出现同名文件时启动报错

问题描述

项目框架springboot+mybatisplus+mybatis,需求中使用webservice,经过各种研究、对比、测试最后决定使用wsimport生成代码。wsimport是jdk自带的webservice客户端工具,可以根据wsdl文档生成客户端调用代码(java代码)位于JAVA_HOME/bin目录下。

wsimport [options] <WSDL_URI>

生成的文件如下:

每个webservice生成的代码都有一些同名的类,如DtZrsv、ObjectFactory,当Springboot启动时悲剧发生了,一长串的异常,整个世界都不好了。

Error creating bean with name 'sqlSessionFactory' defined in class path resource [com/baomidou/mybatisplus/autoconfigure/MybatisPlusAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is org.apache.ibatis.type.TypeException: The alias 'ObjectFactory' is already mapped to the value 'com.example.webservice.ObjectFactory'.

解决路程

看到这个错误,下意识的认为是命名重复,bean工厂实例化的问题,接下来对着文件名和类名一通操作。。。

经过一通折腾还是没有解决问题,于是决定跟踪源码看看到底是啥原因。首先根据错误信息找到MybatisPlusAutoConfiguration类,并在sqlSessionFactory方法设下断点

经过第一轮调试初步确定错误实在方法最后一行return factory.getObject()出错,

@Bean@ConditionalOnMissingBeanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {// TODO 使用 MybatisSqlSessionFactoryBean 而不是 SqlSessionFactoryBeanMybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setVfs(SpringBootVFS.class);..............return factory.getObject();}

facotry.getObject方法

    public SqlSessionFactory getObject() throws Exception {if (this.sqlSessionFactory == null) {afterPropertiesSet(); // 关键代码}return this.sqlSessionFactory;}public void afterPropertiesSet() throws Exception {notNull(dataSource, "Property 'dataSource' is required");state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),"Property 'configuration' and 'configLocation' can not specified with together");SqlRunner.DEFAULT.close();this.sqlSessionFactory = buildSqlSessionFactory(); // 关键代码}

接下来很容易就找到buildSqlSessionFactory,看名称就知道这个地方应该是创建sqlSessionFactory的方法,继续跟踪查找元凶,在单步调试的帮助下找到错误行

protected SqlSessionFactory buildSqlSessionFactory() throws Exception {final Configuration targetConfiguration;............if (hasLength(this.typeAliasesPackage)) {scanClasses(this.typeAliasesPackage, this.typeAliasesSuperType).stream().filter(clazz -> !clazz.isAnonymousClass()).filter(clazz -> !clazz.isInterface()).filter(clazz -> !clazz.isMemberClass()).forEach(targetConfiguration.getTypeAliasRegistry()::registerAlias); //关键代码} public void registerAlias(Class<?> type) {String alias = type.getSimpleName();Alias aliasAnnotation = type.getAnnotation(Alias.class);if (aliasAnnotation != null) {alias = aliasAnnotation.value();}registerAlias(alias, type); //关键代码}public void registerAlias(String alias, Class<?> value) {if (alias == null) {throw new TypeException("The parameter alias cannot be null");}// issue #748String key = alias.toLowerCase(Locale.ENGLISH);if (typeAliases.containsKey(key) && typeAliases.get(key) != null && !typeAliases.get(key).equals(value)) {throw new TypeException("The alias '" + alias + "' is already mapped to the value '" + typeAliases.get(key).getName() + "'.");}typeAliases.put(key, value);}

发现在 targetConfiguration.getTypeAliasRegistry()::registerAlias 产生错误,追踪下去直到registerAlias(String alias, Class<?> value)方法,发现了报错的地方,从代码中可以看出mybatis加载类型别名时,会将别名存储在个Map<String,Class<?>>中,而map内部插入一个key相同的键值对是一定不行的,因此当存在相同类名时会出错。

解决办法

在代码中可以看出配置了typeAliasesPackage才会进入这个方法,因此目前使用最简单粗暴将其配置去除。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java实现pdf/word文字识别,调用OCR提取图片文字聚合
  • 厦门商家微信小程序、抖音、支付宝小程序同步上线
  • C语言宏中“#”和“##”的用法
  • 优先级队列的实现
  • 【uniapp】vue3+vite配置tailwindcss
  • 力扣热题100_链表_234_回文链表
  • ubuntu设置共享文件夹,非虚拟机,服务器版
  • XSS DOM漏洞复现 与DOM 破坏
  • ARM/Linux嵌入式面经(二四):国光电器
  • 雷达气象学(9)——反射率因子图分析(强对流篇)
  • 二十、观察者模式
  • 在postman设置请求里带动态token,看看这两种方法!
  • Python接口自动化之unittest单元测试
  • 深入理解指针(五)
  • 分享一个基于SpringBoot的戏剧戏曲科普平台的设计与实现(源码、调试、LW、开题、PPT)
  • python3.6+scrapy+mysql 爬虫实战
  • [Vue CLI 3] 配置解析之 css.extract
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • HTML-表单
  • iOS小技巧之UIImagePickerController实现头像选择
  • IP路由与转发
  • JS变量作用域
  • MySQL-事务管理(基础)
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • PHP 7 修改了什么呢 -- 2
  • springboot_database项目介绍
  • Sublime Text 2/3 绑定Eclipse快捷键
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 前端工程化(Gulp、Webpack)-webpack
  • 小程序01:wepy框架整合iview webapp UI
  • #565. 查找之大编号
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (初研) Sentence-embedding fine-tune notebook
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (回溯) LeetCode 131. 分割回文串
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (强烈推荐)移动端音视频从零到上手(下)
  • (十八)SpringBoot之发送QQ邮件
  • (十一)图像的罗伯特梯度锐化
  • (四)js前端开发中设计模式之工厂方法模式
  • (四)Linux Shell编程——输入输出重定向
  • (一)Thymeleaf用法——Thymeleaf简介
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)memcache、redis缓存
  • (转)创业的注意事项
  • (转)重识new
  • (轉貼) UML中文FAQ (OO) (UML)
  • (自适应手机端)响应式服装服饰外贸企业网站模板
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?