java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_it

博客记录了MyBatis查询数据库时出现的错误。错误信息显示Type handler在参数映射中为空,无法找到指定的javaType/jdbcType组合。详细展示了错误堆栈信息,推测问题可能出在item对象属性的处理上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2018-08-28 17:13:21 ERROR com.sprucetec.osc.task.ScanBalanceTask scanBalanceInnerNew:114 - ScanBalance Failed!
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
### Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
    at com.sun.proxy.$Proxy20.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:119)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)
    at com.sun.proxy.$Proxy32.getBillBalanceAndMoney(Unknown Source)
    at com.sprucetec.osc.manager.impl.OscCustomerBillManagerImpl.getBillBalanceAndMoney(OscCustomerBillManagerImpl.java:1440)
    at com.sprucetec.osc.manager.impl.OscCustomerBillManagerImpl$$FastClassBySpringCGLIB$$e9ab471c.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:649)
    at com.sprucetec.osc.manager.impl.OscCustomerBillManagerImpl$$EnhancerBySpringCGLIB$$392028c4.getBillBalanceAndMoney(<generated>)
    at com.sprucetec.osc.task.ScanBalanceTask.scanBalanceInnerNew(ScanBalanceTask.java:92)
    at com.sprucetec.osc.task.ScanBalanceTask$2.run(ScanBalanceTask.java:71)
    at com.sprucetec.osc.base.redis.RedisLock.wrap(RedisLock.java:199)
    at com.sprucetec.osc.task.ScanBalanceTask.scanBalanceByHand(ScanBalanceTask.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
### Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:26)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:111)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)
    at sun.reflect.GeneratedMethodAccessor221.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358)
    ... 30 more
Caused by: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_item_0'.  It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
    at org.apache.ibatis.mapping.ParameterMapping$Builder.validate(ParameterMapping.java:117)
    at org.apache.ibatis.mapping.ParameterMapping$Builder.build(ParameterMapping.java:104)
    at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.buildParameterMapping(SqlSourceBuilder.java:122)
    at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.handleToken(SqlSourceBuilder.java:66)
    at org.apache.ibatis.parsing.GenericTokenParser.parse(GenericTokenParser.java:53)
    at org.apache.ibatis.builder.SqlSourceBuilder.parse(SqlSourceBuilder.java:45)
    at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:43)
    at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:278)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:75)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108)
    ... 35 more

 

 

 

应该此处的item 是个对象,应该是放该对象的属性

<think>我们正在处理一个MyBatis异常:`java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'params'`。这个异常通常发生在MyBatis(或MyBatis Plus)尝试处理一个参数时,找不到合适的类型处理器(TypeHandler)。具体来说,这里涉及到的属性是`params`,其类型为`java.util.Map`。 根据引用的错误信息,特别是引用[1]和[3],错误信息指出: > Type handler was null on parameter mapping for property 'params'. It was either not specified and/or could not be found for the javaType (java.util.Map) : jdbcType (null) combination. 这意味着MyBatis在尝试将Java类型`java.util.Map`转换为JDBC类型时,没有找到合适的类型处理器。可能的原因和解决方案如下: ### 原因分析 1. **未指定JDBC类型**:在参数映射中,没有为Map类型的参数指定`jdbcType`。MyBatis在处理`Map`类型时,可能无法自动推断出合适的JDBC类型。 2. **缺少自定义类型处理器**:如果`Map`中包含复杂类型,可能需要自定义类型处理器(TypeHandler)来处理这些类型,但未配置或未正确注册。 3. **参数配置问题**:在Mapper方法中,可能使用了`@Param`注解,并且参数名为`params`,但MyBatis在处理这个参数时遇到了问题。 ### 解决方案 #### 方案1: 为参数指定`jdbcType` 在Mapper XML文件中,为参数明确指定`jdbcType`。例如,如果你使用的是`Map`,可以尝试指定为`OTHER`(因为`Map`不是简单的类型,而`OTHER`表示数据库特定的非标准类型)。但请注意,`jdbcType`通常在参数是单个值且需要明确数据库类型时使用,对于`Map`,这种方法可能不直接适用。 #### 方案2: 检查参数传递方式 在Mapper接口中,如果使用`@Param`注解指定参数名为`params`,可以尝试去掉`@Param`注解,或者改变参数传递方式。例如,将参数封装到一个DTO对象中,而不是直接使用`Map`。 #### 方案3: 注册自定义类型处理器 如果`Map`中包含复杂对象,需要为这些对象编写自定义类型处理器,并在MyBatis配置中注册。 例如,编写一个处理`Map`的类型处理器(虽然MyBatis本身已经内置了对`Map`的处理,但可能在某些情况下需要自定义): ```java public class MapTypeHandler extends BaseTypeHandler<Map<String, Object>> { // 实现方法 } ``` 然后在MyBatis配置文件中注册: ```xml <typeHandlers> <typeHandler handler="com.example.MapTypeHandler"/> </typeHandlers> ``` 但在大多数情况下,MyBatis内置的`MapTypeHandler`已经足够。因此,这个异常可能是因为MyBatis无法自动识别到内置的处理器,所以我们可以尝试显式指定类型处理器。 在Mapper XML中,可以这样指定: ```xml <insert id="insertSomething"> INSERT INTO table (column) VALUES (#{params, typeHandler=org.apache.ibatis.type.MapTypeHandler}) </insert> ``` 但是,请注意,`org.apache.ibatis.type.MapTypeHandler`是MyBatis内置的,用于处理`Map`。如果你使用的是MyBatis Plus,可能有自己的类型处理器,或者需要检查是否因为版本问题导致内置处理器未被正确加载。 #### 方案4: 检查MyBatis版本和配置 有时,版本不兼容或配置错误可能导致内置类型处理器无法正确注册。确保使用的MyBatis版本稳定,并且没有破坏性变更。 #### 方案5: 使用MyBatis Plus时的特殊处理 引用[4]提到一个使用`removeByIds`方法时传递了错误类型的参数(应该传递id的List,而不是实体对象的List)导致类似异常。因此,请检查你的代码中是否在应该传递简单类型(如Long, String等)的地方传递了复杂对象(如Map)。例如,在调用MyBatis Plus的`removeByIds`方法时,必须传递主键的集合,而不是实体集合。 #### 方案6: 检查参数名称 在Mapper接口中,如果方法参数是一个`Map`,并且使用了`@Param("params")`,那么确保在XML中引用的是`params`。如果参数名不一致,也可能导致问题。 ### 总结建议 1. 首先,检查代码中是否有类似引用[4]中的错误,即传递了错误类型的参数(如将实体List传递给需要id List的方法)。 2. 如果使用的是Mapper XML,尝试在参数位置显式指定类型处理器,例如:`#{params, typeHandler=org.apache.ibatis.type.MapTypeHandler}`。 3. 如果问题仍然存在,考虑将参数`Map`封装到一个POJO中,然后传递POJO,避免直接使用`Map`。 4. 确保MyBatis配置正确,并且没有遗漏类型处理器的注册(尤其是自定义的)。 如果以上方法都不能解决问题,请提供更多的代码上下文(如Mapper接口方法、XML映射片段、调用代码等),以便进一步分析。 ### 相关问题 1. MyBatis中如何自定义类型处理器(TypeHandler)? 2. MyBatis Plus的`removeByIds`方法应该传递什么类型的参数? 3. 如何为MyBatis的Mapper参数指定`jdbcType`? 4. 在MyBatis中,使用`Map`作为参数有什么注意事项?</think>### MyBatis 类型处理器缺失异常分析与解决方案 您遇到的 `java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'params'` 错误,是由于 MyBatis/MyBatis Plus 在处理 `java.util.Map` 类型参数时找不到合适的类型处理器(TypeHandler)导致的。以下是详细分析和解决方案: --- ### 错误原因分析 1. **类型处理器缺失** MyBatis 需要明确的类型处理器将 Java 类型(如 `Map`)转换为 JDBC 类型。当参数为 `Map` 且未指定处理器时,会抛出此异常。 2. **参数类型不匹配** 常见于 MyBatis Plus 的批量操作方法(如 `removeByIds()`),要求传入 **主键集合**(如 `List<Long>`),但实际传递了 **实体对象集合**(如 `List<Entity>`),导致类型解析失败[^4]。 3. **复杂类型未配置** 使用 `Map` 作为参数时,若包含嵌套对象或特殊数据类型(如枚举、自定义对象),需显式配置类型处理器。 --- ### 解决方案 #### ✅ 方案1:检查批量操作方法参数(推荐优先尝试) **问题代码示例**: ```java // 错误:传入实体对象集合而非ID集合 List<User> userList = userService.listByIds(ids); userService.removeByIds(userList); // 触发异常 ``` **修复方案**: 提取主键值集合作为参数: ```java List<Long> idList = userList.stream() .map(User::getId) .collect(Collectors.toList()); userService.removeByIds(idList); // 传入ID集合[^4] ``` #### ✅ 方案2:显式指定类型处理器 在 Mapper XML 中为 `Map` 参数指定类型处理器: ```xml <insert id="insertData"> INSERT INTO table VALUES (#{params, typeHandler=org.apache.ibatis.type.MapTypeHandler}) </insert> ``` #### ✅ 方案3:注册全局类型处理器 在 `mybatis-config.xml` 中注册内置 `Map` 处理器: ```xml <typeHandlers> <typeHandler handler="org.apache.ibatis.type.MapTypeHandler" javaType="java.util.Map"/> </typeHandlers> ``` #### ✅ 方案4:避免直接使用 `Map` 作为参数 改用 DTO 对象封装参数: ```java // Java代码 @Getter @Setter public class QueryDTO { private String key; private Object value; } // Mapper接口 List<User> selectByMap(@Param("params") QueryDTO params); ``` --- ### 关键注意事项 1. **MyBatis Plus 批量操作规范** `removeByIds()`, `selectBatchIds()` 等方法必须传入 **主键值集合**(如 `List<Long>`),而非实体集合[^4]。 2. **复杂类型处理** 如果 `Map` 中包含自定义对象,需为该对象实现 `BaseTypeHandler`: ```java public class CustomTypeHandler extends BaseTypeHandler<MyObject> { // 实现类型转换逻辑 } ``` 3. **参数别名一致性** 确保 `@Param` 注解名称与 XML 中的参数名匹配: ```java // Mapper接口 void update(@Param("params") Map<String, Object> map); ``` ```xml <!-- XML --> <update id="update"> UPDATE table SET field = #{params.key} <!-- 名称匹配 --> </update> ``` --- ### 相关问题 1. MyBatis Plus 中 `removeByIds()` 方法正确的参数类型是什么? 2. 如何为自定义 Java 对象实现 MyBatis 类型处理器? 3. 在 MyBatis 中使用 `Map` 作为参数有哪些最佳实践? 4. MyBatis 类型处理器的工作原理是什么? > 解决方案参考: > [^1]: MyBatis 参数映射时类型处理器缺失的核心错误描述 > [^4]: MyBatis Plus 批量操作方法的参数规范示例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潇凝子潇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值