首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

MyBatis SqlSession 未註冊同步化異常:非配置原因深度排查與解決

     編輯:關於SqlServer

異常現象

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@69d4fb43] was not registered for synchronization because synchronization is not active
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@69d4fb43]

網路常見解答指向「配置檔錯誤」,但專案運行已久、配置無變更,新增方法才觸發異常,排除配置問題。

根因定位

關閉統一異常處理,直接列印堆疊追蹤:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: 
There is no getter for property named 'departid' in 'class java.lang.String'

關鍵錯誤

There is no getter for property named 'departid' in 'class java.lang.String'

程式碼分析

Mapper XML 中對參數 departid 進行判斷:


    AND depart_id = #{departid}

Service 層呼叫:

int count = mapper.selectCount(departId);  // 直接傳遞 String 參數

根因解析

MyBatis 單一基本型別參數(String、Integer 等)時,參數名稱預設為參數本身的類別名稱(如 java.lang.String),不具備屬性 getter。OGNL 表達式 departid != null 嘗試存取 String.departid 導致 ReflectionException。

解決方案

方案一:@Param 註解指定參數名(推薦)

int selectCount(@Param("departid") String departid);

方案二:封裝為 Map 或 DTO 物件

// Map 方式
Map params = new HashMap<>();
params.put("departid", departId);
int count = mapper.selectCount(params);

// DTO 方式
public class QueryParam {
    private String departid;
    // getter/setter
}
int selectCount(QueryParam param);

原理補充

  • 單一參數且非集合/Map/DTO → 參數名 = 類別簡名(如 string, int),無屬性存取
  • @Param 明確指定參數名,OGNL 可正確解析
  • 集合/陣列會自動包裝為 collection/array,Map 直接以鍵值存取

總結

「SqlSession 未註冊同步化」是表象,真正原因是參數綁定失敗導致事務未正常開啟。單一基本型別參數務必加 @Param 或封裝為物件,避免 OGNL 解析錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved