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

iBatis 搭配 OSCache 緩存踩坑:Windows 下 FileNotFoundException 根因與修復

     編輯:Java 相關知識

現象描述

環境:Windows 7 + iBatis 2.3.0.677 + OSCache 2.4.1。配置磁盤緩存時,查詢執行第二次拋出 java.io.FileNotFoundException: 文件名、目錄名或卷標語法不正確。

配置片段

iBatis 映射文件

<cacheModel type="OSCACHE" id="productCache">
  <flushOnExecute statement="Product.insert"/>
  <flushOnExecute statement="Product.delete"/>
</cacheModel>
<select id="getById" cacheModel="productCache" parameterClass="int" resultClass="Product">
  select id, name, description as desc1 from test_product where id = #value#
</select>

OSCache 配置

cache.memory=false
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.path=e:\\OSCache\\cache
cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache

異常堆疊關鍵資訊

Unable to write 'e:\OSCache\cache\application\1991729862|2162672802|5|Product_31getById|62996507|_49_50_51...|executeQueryForObject.cache'
Exception: java.io.FileNotFoundException, Message: 文件名、目錄名或卷標語法不正確

根因分析

iBatis 生成的緩存 Key 由 CacheKey.toString() 產生,格式為:

hashcode|checksum|param1|param2|...|sql語句

其中包含大量 豎線符號 `|`。Windows 檔案系統禁止檔名包含 `|`,Linux 則允許,導致跨平台不相容。

修復方案

修改 com.ibatis.sqlmap.engine.cache.CacheKey.toString(),將 `|` 替換為合法字元(如 `-`):

public String toString() {
    StringBuffer buf = new StringBuffer().append(hashcode).append('|').append(checksum);
    for (int i = 0; i < paramList.size(); i++) {
        buf.append('|').append(paramList.get(i));
    }
    return buf.toString().replace('|', '-'); // 關鍵修復
}

編譯後將 CacheKey.class 替換至 iBatis JAR 或專案 classes 目錄(優先載入)。

後續注意事項

  1. 其他緩存實現同樣依賴 CacheKey,若啟用檔案持久化同樣會遇到此問題。
  2. Key 過長可能超過檔案系統限制(如 255 字元),建議縮短緩存目錄層級或自訂 toString() 縮短邏輯。
  3. CacheKey.equals() 邏輯決定緩存命中規則,需確保參數順序、類型一致性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved