浅析mybatis懒加载导致无法序列化的问题、Json序列化对象时错误Could not write JSON: No serializer found for class

一、问题背景

  在使用 MyBtais resultMap 一对多时,查数据报错:

Unable to serialize claims object to json: Unable to serialize object: 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) (through reference chain: io.jsonwebtoken.impl.DefaultClaims[\"userInfo\"]->top.jybill.domain.MyUser_$$_jvst2e5_0[\"handler\"])

  起初不知道为啥,查资料了解到,总而言之:Bug原因是 - 因为mybatis的懒加载原因

复制代码
<resultMap id="order" type="order">
        <id property="id" column="id" />
        <result property="orderNum" column="orderNum" />
        <result property="orderTime" column="orderTime" />
        <result property="orderStatus" column="orderStatus" />
        <result property="peopleCount" column="peopleCount" />
        <result property="payType" column="payType" />
        <result property="orderDesc" column="orderDesc" />
        <association column="productId" property="product"
                     select="top.jybill.dao.IProductDao.findProductById"
                     fetchType="eager" />
</resultMap>
复制代码

  起初我没有fetchType属性,默认是lazy懒加载, 修改成eager后成功序列化

  因为我是一对一的,一般情况不需要懒加载,如果是一对多必须懒加载的情况则需给实体类加上 @JsonIgnoreProperties(value = "handler") 注解

二、解决方案

1、在实体类上加注解:@JsonIgnoreProperties(value = {"handler"})

  在所有相关的类前加上@JsonIgnoreProperties, 作用是json序列化时忽略bean中的一些属性序列化和反序列化时抛出的异常

2、或者在 <collection> 中加入:fetchType="eager"

3、关闭/不启用mybatis懒加载(mybatis默认关闭)

三、问题分析

  在mybatis集成springmvc,假如mybatis采用了懒加载,而在控制器中把返回的数据序列化成Json格式字符串,则会抛出异常:

There was an unexpected error (type=Internal Server Error, status=500).
Could not write JSON: No serializer found for class org.apache.ibatis.reflection.factory.DefaultObjectFactory and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

  原因是MyBatis代理的实体对象被代理后的类多了一个handler的属性,之后Jackson在对该代理类做序列化时,由于找不到对应的 getter,异常就抛出来了。

  解决方法:

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

@JsonIgnoreProperties(value= {"handler"})
public class Student implements Serializable {}

2、在MyBatis的映射文件中把懒加载改成即时加载 fetchType="eager" ,默认值是 "lazy":

<resultMap type="Student" id="studentMap">
   <association property="grade" column="gradeId"
     select="com.bdqn.dao.GradeDao.findById" fetchType="eager"></association>
</resultMap>

 

posted @   古兰精  阅读(1887)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2018-06-15 深入理解VUE样式style层次分析
2017-06-15 浅析如何自定义Java异常类且修改返回http状态码及解决状态码始终是200的问题和303状态码理解
点击右上角即可分享
微信分享提示