Spring Boot+Java11+MyBatis注解方式下@Many注解失效无法加载关联集合
问题原因及解决方案
1. 核心错误:@Result的column属性配置错误
@Many注解的column属性需要填写主查询返回结果集中的列名,MyBatis会将该列的值作为参数传递给关联的子查询方法。
你的主查询已经将INFORMATION_OBJECT表的ID字段别名设置为id,但你在配置时写的是数据库表的全限定字段SCHEMA_ONE.INF_OBJ_CLASIFFIER.INFORMATION_OBJECT_ID,主查询结果集里不存在该列,MyBatis无法获取到传递给子查询的参数,因此不会触发selectCredits方法执行。
2. 补充:主查询基础字段映射建议
即使开启了驼峰自动映射,也建议在关联查询的@Results中显式声明主键映射,避免MyBatis聚合结果时出现异常。
修正后的Mapper代码:
@Mapper public interface InformationObjectMapper { @SelectProvider(type = InformationObjectSqlProvider.class, method = "selectByInventoryNumberConditionAccountingNumber") @Results(value = { // 显式声明主键映射,id=true标记为主键 @Result(property = "id", column = "id", id = true), // 基础字段可根据实际情况选择是否显式声明,显式声明兼容性更高 @Result(property = "titleLt", column = "titleLt"), @Result(property = "accountingNumber", column = "accountingNumber"), @Result(property = "inventoryNumber", column = "inventoryNumber"), @Result(property = "referenceYear", column = "referenceYear"), @Result(property = "duration", column = "duration"), @Result(property = "propertyRights", column = "propertyRights"), // 修正column为 主查询返回的id列,作为参数传递给selectCredits @Result(property = "creditsList", column = "id", javaType = Set.class, many = @Many(select = "selectCredits")) }) List<InformationObjectMergedWithCopyrights> selectByInventoryNumberConditionAccountingNumber(@Param("reportParamsDao") InventoryNumberReportParamsDao reportParamsDao); @Select("SELECT * FROM SCHEMA_ONE.INF_OBJ_CLASSIFIER ioc WHERE ioc.INFORMATION_OBJECT_ID = #{informationObjetId} AND ioc.\"TYPE\" = 'CREDIT' ") @Results(value = { @Result(property = "bavicLabel", column = "BAVIC_LABEL"), @Result(property = "bavicRole", column = "ROLE") }) Set<BavicCredit> selectCredits(@Param("informationObjetId") Long informationObjetId); }
验证排查建议
可以在Spring Boot配置文件中开启MyBatis SQL日志打印,确认子查询是否正常触发、参数传递是否正确:
# application.yml 配置 mybatis: configuration: # 控制台打印执行的SQL及参数 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
如果子查询已经触发但结果仍为空,需要检查:
- 传递给子查询的id值是否和数据库
INF_OBJ_CLASSIFIER表中的INFORMATION_OBJECT_ID匹配 - Oracle大小写敏感,确认表中
TYPE字段存储的值确实是大写的CREDIT - 检查
INF_OBJ_CLASSIFIER表名拼写是否正确(之前配置的全限定名中CLASIFFIER拼写少了字母S,需确认实际表名)
内容的提问来源于stack exchange,提问作者Dainius Java
相关产品推荐
相关产品推荐

