使用Mybatis-Plus时抛出UnsupportedOperationException求助
问题排查与解决
核心原因分析
堆栈指向org.apache.ibatis.reflection.wrapper.CollectionWrapper.get,说明MyBatis在处理参数时,试图把集合对象当成普通Java对象去获取属性,而集合类(比如List)本身没有对应的属性方法,触发了UnsupportedOperationException。
具体排查步骤
1. 检查Mapper XML中对roleIds的SQL写法
这是最可能的问题点:
- 错误示例:如果XML中错误地将集合作为对象取属性,比如写了
#{dto.roleIds.roleId}或者直接引用集合的某个不存在的属性,MyBatis会尝试用CollectionWrapper去get这个属性,直接抛出异常。 - 正确写法:遍历集合应该用
<foreach>标签,比如关联员工角色表的筛选逻辑:
<select id="pageWithRolesId" resultMap="EmployeeResultMap"> SELECT e.* FROM employee e <where> <if test="dto.username != null and dto.username != ''"> AND e.username LIKE CONCAT('%', #{dto.username}, '%') </if> <if test="dto.email != null and dto.email != ''"> AND e.email LIKE CONCAT('%', #{dto.email}, '%') </if> <if test="dto.roleIds != null and dto.roleIds.size() > 0"> AND e.id IN ( SELECT er.employee_id FROM employee_role er WHERE er.role_id IN <foreach collection="dto.roleIds" item="roleId" open="(" separator="," close=")"> #{roleId} </foreach> ) </if> </where> </select>
注意:<foreach>的collection属性要正确指向dto.roleIds,确保参数路径正确。
2. 确认EmployeePageQueryDTO的roleIds字段类型
- 确保
roleIds是可变集合类型(比如ArrayList<Integer>),如果是用Collections.unmodifiableList()生成的不可变集合,可能会导致MyBatis反射操作时出现异常。 - DTO字段定义示例:
public class EmployeePageQueryDTO { private Long current; private Long size; private String username; private String email; // 用ArrayList初始化,避免不可变集合问题 private List<Integer> roleIds = new ArrayList<>(); // getter/setter }
3. 检查Employee实体类的rolesId字段注解
因为rolesId是非数据库字段,必须添加@TableField(exist = false)注解,避免MyBatis-Plus在自动生成SQL或结果映射时错误处理该字段:
public class Employee { // 其他数据库字段 @TableField(exist = false) private List<Integer> rolesId; // getter/setter }
4. 开启MyBatis日志验证参数
配置MyBatis日志打印,确认参数传递是否正确:
在application.yml中添加:
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
运行后查看控制台输出的SQL和参数,确认roleIds确实是包含[2,4]的集合,且参数引用路径正确。
内容的提问来源于stack exchange,提问作者gameplayer47
相关产品推荐
相关产品推荐

