MyBatis关联查询和懒加载错误
MyBatis关联查询和懒加载错误
今天在写项目时遇到了个BUG。先说一下背景,前端请求更新生产订单状态,后端从前端接收到生产订单ID进行查询,然后就有问题了。
先看控制台报错:
org.apache.ibatis.executor.ExecutorException: Statement returned more than one row, where no more than one was expected.
很明显,预期查出一条记录的结果查出了多条记录。因为在实现 service 层代码时直接返回的是 DAO 对象,而 DAO 是通过 MyBatis
实现的,因此直接对 DO 设计和 MyBatis 接口实现进行排查。
核心代码如下
DO类对象
//生产订单
public class ProduceDO extends AbstractDO implements Serializable {
//生产任务
private List<OrderProduceDO> orderProduceList;
}
接口实现
<resultMap id="ProduceDO" type="com.bootdo.erp.domain.ProduceDO">
<collection property="orderProduceList" select="com.bootdo.erp.dao.OrderProduceDao.list"
javaType="com.bootdo.erp.domain.OrderProduceDO"
column="{'produceId' = id}" fetchType="lazy">
</collection>
</resultMap>
<select id="get" resultMap="ProduceDO">
select `id`,`form_Id`,`proc_Ins_Id`,`number`,`type`,`start_time`,`end_time`,`create_by`,`create_time`,`remarks`,`status`,`del_flag` from erp_produce where id = #{value}
</select>
检查了一遍关联 DO 的代码实现,并且使用数据库直接进行数据查询,没找到问题。回看接口实现,发现关联属性 orderProduceList
的类型在 DO 里和 Mybatis 中不一致,将 javaType="com.bootdo.erp.domain.OrderProduceDO"
改为 javaType="java.utils.List"
或删除该行代码(Mybatis 已对 Java 常用类型进行了映射),运行,问题解决,nice!
but,再次运行,控制台又报了一个新错误:
org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactoryEnhancedResultObjectProxyImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.bootdo.common.domain.R["produce"]->com.bootdo.erp.domain.ProduceDO_$$_jvst156_0["handler"])
黑人问号??? 虚假程序员打开百度,看到了这个 Mybatis懒加载——返回前端数据 json序列化错误,意思是错误是由懒加载导致的。
解决方法:在相关类上面加上 @JsonIgnoreProperties(value = { "handler"})
@JsonIgnoreProperties(value = { "handler"})
public class ProduceDO extends AbstractDO implements Serializable
@JsonIgnoreProperties(value = { "handler"})
public class OrderProduceDO extends AbstractDO implements Serializable
@JsonIgnoreProperties(value = { "handler"})
public abstract class AbstractDO implements Serializable {
再次运行,成功!
参考博客:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步