使用MyBatis Generator生成多表后遇Criterion别名冲突报错求助
嘿,我刚好碰到过一模一样的问题!你这是MyBatis自动生成的两个Example内部类Criterion别名冲突了——GameListExample和BetRecdExample里的内部类都叫Criterion,MyBatis默认会把内部类的简单类名当成别名,这就直接撞车了,所以才会触发那个TypeException: 别名'Criterion'已映射到值'com.good.game.domain.def.GameListExample$Criterion'的初始化异常。
给你几个亲测有效的解决方案,按推荐程度排序:
1. 修改MyBatis Generator配置,生成唯一别名
这是最根本的解决办法,从代码生成环节就避免冲突。在你的MBG配置文件里,给每个table标签加上exampleInnerClassTypeAlias属性,指定每个Criterion内部类的唯一别名:
<table tableName="game_list" domainObjectName="GameList"> <!-- 给GameList的Criterion指定唯一别名 --> <property name="exampleInnerClassTypeAlias" value="GameListCriterion"/> </table> <table tableName="bet_recd" domainObjectName="BetRecd"> <!-- 给BetRecd的Criterion指定唯一别名 --> <property name="exampleInnerClassTypeAlias" value="BetRecdCriterion"/> </table>
重新生成代码后,MBG会在生成的Example类里给内部Criterion类加上@Alias注解,用你指定的唯一名称,这样MyBatis就不会把它们当成同一个别名了。
2. 升级MyBatis/MyBatis Generator版本
有些旧版本的MyBatis或MBG在处理内部类别名时没考虑到这种冲突,升级到较新的版本(比如MyBatis 3.5.10+、MBG 1.4.1+)可能已经默认解决了这个问题——新版本会自动给内部类生成包含外部类名的别名,比如GameListExample_Criterion,自然就不会冲突了。
3. 关闭自动别名扫描,手动指定别名
如果暂时不想改MBG配置或升级版本,可以在Spring Boot配置里关闭MyBatis的自动别名扫描,然后手动给每个Criterion类指定唯一别名。比如在application.yml里:
mybatis: # 留空关闭自动扫描别名 type-aliases-package: "" configuration: type-aliases: - type: com.good.game.domain.def.GameListExample$Criterion alias: GameListCriterion - type: com.good.game.domain.def.BetRecdExample$Criterion alias: BetRecdCriterion
不过这个方法比较繁琐,后续新增表还要手动加别名,适合小项目临时救急。
4. 自定义TypeAliasRegistry处理内部类别名
这个稍微复杂点,适合有定制需求的场景:写一个自定义的TypeAliasRegistry子类,在注册内部类别名时自动加上外部类的名称作为前缀,然后配置MyBatis使用这个自定义的Registry。不过一般前面三个方案就足够解决问题了,这个算是进阶玩法。
最后提醒一下:不管用哪个方案,记得重新生成代码(如果涉及MBG的话),然后清理项目缓存、重启应用,应该就能解决那个Bean初始化的异常了。
内容的提问来源于stack exchange,提问作者David

