之前将Hibernate的实体类及其映射文件也放到项目中,由于有多个项目使用同一个数据库,Hibernate实体类和映射文件重复,不便于维护和升级。因此将其抽取出来,打成jar包,再引入回项目。
实际操作中,发现个诡异的问题:项目运行没问题,但是JUnit单元测试不能运行(方法使用了HQL语句时),总是报org.hibernate.hql.ast.QuerySyntaxException的错误,说明没有找到映射文件,不知道为何。具体报错信息如下:
org.springframework.orm.hibernate3.HibernateQueryException: Fsettlement is not mapped [select f from Fsettlement f where 1=1 and f.fsettlementId = :fsettlementId ]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: Fsettlement is not mapped [select f from Fsettlement f where 1=1 and prePayType='PRE_PAY' and f.supplierId = :supplierId and f.payTime >= :startDate and f.payTime <= :endDate and f.stockEleSupplierId = :stockEleSupplierId and f.payType = :payType and f.fsettlementId = :fsettlementId ] ... Caused by: org.hibernate.hql.ast.QuerySyntaxException: Fsettlement is not mapped [select f from Fsettlement f where 1=1 and prePayType='PRE_PAY' and f.supplierId = :supplierId and f.payTime >= :startDate and f.payTime <= :endDate and f.stockEleSupplierId = :stockEleSupplierId and f.payType = :payType and f.fsettlementId = :fsettlementId ] ... |
Hibernate的配置如下:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingJarLocations">
<list>
<value>WEB-INF/lib/model-core*.jar</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.stock.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.stock.show_sql}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.stock.cache.provider_class}</prop>
</props>
</property>
</bean>
Google 上找到的方法一一试过,也许是错误太低级,根本就没人会犯此错误吧。找不到解决方法,但是项目还是要继续。分析了一下,文件是否在 jar 中,对于 JUnit 来说,都是从 classpath 中读取,与其他无关。
于是尝试改回原来的配置,发现还是不行;
难道是相对路径,不是绝对路径?于是将”/”去掉,还是不行;
难道要指定文件才行吗?再一次尝试,竟然成功了!不明白,Hibernate不是会自动扫描的嘛;虽然成功了,但是要一一指定文件名,肯定不现实;
于是各种尝试,将结果一一记录,
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations">
<value>classpath*:com/allen/hbm/*.hbm.xml</value>
<!--<value>classpath:com/allen/hbm/*.hbm.xml</value>--> <!-- 此种写法报错,不能识别 -->
<!--<value>classpath*:/com/alenn/hbm/</value>--> <!-- 此种写法报错,不能识别 -->
<!--<value>classpath*:/com/allen/hbm</value>--> <!-- 此种写法报错,不能识别 -->
<!--<value>classpath*:com/allen/hbm/</value>--> <!-- 此种写法报错,不能识别 -->
<!--<value>classpath*:com/allen/hbm</value>--> <!-- 此种写法报错,不能识别 -->
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.stock.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.stock.show_sql}</prop>
<prop key="hibernate.cache.provider_class">${hibernate.stock.cache.provider_class}</prop>
</props>
</property>
</bean>
问题虽然解决了,但还有一点还是不明白,为何项目运行没问题呢?