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.JavassistProxyFactory\(EnhancedResultObjectProxyImpl]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 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: 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 {
再次執行,成功!
參考部落格: