Mybatis懒加载时,springMVC返回JSON异常 Could not write JSON: No serializer found for class

在mybatis集成springmvc时,假如mybatis采用了懒加载,而springmvc中利用@ResponseBody注解返回实体类的JSON时会抛异常:

Could not write JSON: No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS);
先看出现问题的代码:

首先是controller中返回的是responsebody:

复制代码

    /**
     * 根据订单ID查询订单
     * @param orderId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/query/{orderId}" ,method = RequestMethod.GET)
    public Order queryOrderById(@PathVariable("orderId") String orderId) {
        return orderService.queryOrderById(orderId);
    }

复制代码

 

service中的代码:

    public Order queryOrderById(String orderId) {
        Order order = orderDao.queryOrderById(orderId);
        return order;
    }
    public Order queryOrderById(String orderId) {
        return this.orderMapper.queryByID(orderId);
    }

调用的mapper.xml中使用了懒加载:

复制代码

    <resultMap type="Order" id="pojoResultMap" autoMapping="true">
        <id column="order_id" property="orderId"/>
        <association property="orderShipping" javaType="OrderShipping" column="order_id" select="queryOrderShippingByOrderId" autoMapping="true" fetchType="lazy"></association>
        <collection property="orderItems" javaType="Arraylist" ofType="OrderItem" autoMapping="true" select="queryOrderItemByOrderId" column="order_id" fetchType="lazy">
        </collection>
    </resultMap>

复制代码

这个时候测试就会上面的异常.

经过调试后发现,原来service中执行过queryByID的方法后,返回的实体类Order被做了代理,如下:

可以看到,被代理后的Order类多了一个handler的属性,之后Jackson在对该代理类做序列化时,由于找不到对应的getter,异常就抛出来辣!

解决方法:

在被代理的Order类上加上 @JsonIgnoreProperties(value = "handler") 注解,让Jackson序列化时忽略handler属性:

 

 

 问题解决!

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个报错一般是因为 Mybatis 找不到对应的 TypeHandler 来处理数据库中的某个字段。TypeHandler 是 Mybatis 中用来将 Java 类型与 JDBC 类型进行转换的组件。 解决这个问题的方法是在 Mybatis 的配置文件中配置对应的 TypeHandler。具体的步骤如下: 1. 找到报错的字段,确定它的类型和对应的 JDBC 类型。一般来说,Mybatis 内置了一些常用类型的 TypeHandler,比如 String、Integer、Long 等,如果你使用的类型是内置类型,那么可以直接使用 Mybatis 内置的 TypeHandler。 2. 如果你使用的类型不是内置类型,那么需要自定义一个 TypeHandler。自定义 TypeHandler 的步骤如下: a. 实现 TypeHandler 接口,或者继承 BaseTypeHandler 类。 b. 在 TypeHandler 中实现两个关键方法:setNonNullParameter 和 getNullableResult。setNonNullParameter 用来将 Java 类型转换为 JDBC 类型,getNullableResult 用来将 JDBC 类型转换为 Java 类型。 c. 将自定义的 TypeHandler 注册到 Mybatis 的配置文件中。 例如,假设你有一个 User 类,其中有一个 Gender 字段,它的类型是枚举类型 GenderEnum。那么你需要定义一个 GenderEnumTypeHandler 类来处理这个字段,具体实现代码如下: ``` public class GenderEnumTypeHandler extends BaseTypeHandler<GenderEnum> { @Override public void setNonNullParameter(PreparedStatement ps, int i, GenderEnum parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.toString()); } @Override public GenderEnum getNullableResult(ResultSet rs, String columnName) throws SQLException { String value = rs.getString(columnName); return GenderEnum.fromString(value); } @Override public GenderEnum getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String value = rs.getString(columnIndex); return GenderEnum.fromString(value); } @Override public GenderEnum getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String value = cs.getString(columnIndex); return GenderEnum.fromString(value); } } ``` 其中,GenderEnum.fromString(value) 是一个静态方法,用来将字符串转换为 GenderEnum 类型。 然后,在 Mybatis 的配置文件中注册这个 TypeHandler,具体代码如下: ``` <typeHandlers> <typeHandler handler="com.example.GenderEnumTypeHandler"/> </typeHandlers> ``` 注意,这里的 handler 属性是 GenderEnumTypeHandler 类的全限定名。 这样,在使用 Mybatis 进行查询,就不会再出现 No typehandler found for property 的报错了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值