將 Hibernate 實體類與映射文件(.hbm.xml)抽取打包為獨立 JAR(model-core.jar),引入多模組項目。主應用啟動正常,但 JUnit 單元測試報錯:
org.hibernate.hql.ast.QuerySyntaxException: Fsettlement is not mapped
[select f from Fsettlement f where ...]
明確提示「實體未映射」,說明 SessionFactory 未正確加載 JAR 內的映射文件。
<property name="mappingJarLocations">
<list><value>WEB-INF/lib/model-core*.jar</value></list>
</property>
Spring 啟動上下文時無法解析 WEB-INF/lib/ 相對路徑(非 Web 環境)。
| 配置值 | 結果 |
|---|---|
classpath*:com/allen/hbm/*.hbm.xml | ✅ 成功 |
classpath:com/allen/hbm/*.hbm.xml | ❌ 無法識別 |
classpath*:/com/alenn/hbm/ | ❌ 路徑錯誤+無法識別 |
classpath*:/com/allen/hbm | ❌ 無法識別 |
WEB-INF/lib/;JUnit 運行於標準 Java 應用上下文,ClassPath 僅包含 target/classes、target/test-classes 及 Maven 依賴 JAR 根目錄。mappingJarLocations 要求 Spring 解析 JAR 文件路徑並掃描內部資源,依賴特定 ClassLoader 能力;mappingLocations 配合 classpath*: 前綴,委託 ClassLoader 直接加載資源流,兼容性更強。classpath*: 表示掃描所有 ClassPath 路徑下匹配的資源;classpath: 僅取第一個匹配項。JAR 內資源路徑為 com/allen/hbm/xxx.hbm.xml(無前導斜槓)。<property name="mappingLocations">
<value>classpath*:com/allen/hbm/*.hbm.xml</value>
</property>
classpath*: + 相對包路徑通配符,避免絕對路徑、WEB-INF 等環境強耦合寫法com/allen/hbm/),而非 JAR 根目錄applicationContext-test.xml,確保資源路徑一致性packagesToScan(需實體類帶註解)或程序化配置 LocalSessionFactoryBeanMapping file: com/allen/hbm/xxx.hbm.xml 字樣<class name="..."> 一致核心心法:資源加載路徑需與 ClassLoader 能力匹配,通配符語義要精確。