引子
==============================
最近一个项目,需要将前端应用系统与后端控制台分别发布.但是使用的是同一个数据库.为了代码统一,我决定将Hibernate的实体类(pojo或ho)和hbm文件单独打入一个jar包中复用.
实践第一步:抽取实体类与hbm入jar包.
==============================
在这一步,很多人可能和我一样,以往对于Hibernate打入jar包的做法,只是停留在概念上,从未真正实践过.一般都会将实体类与hbm从原项目中抽取出来,单独做成一个项目.
建立实体类库:
在Netbeans中很简单,新建一个Java类库项目,比如叫ho_prj,将实体类放进[源码]目录中.当然,项目中还需要引入相关的类库,比如Hibernate3.jar等.否则编译无法通过.
这时,原本的项目,应该会提示有编译错误.因为实体类都被移走了,引用到它们的类自然就出错了.
接下来,将右击原项目,进入属性窗口.在库一页中,选择引入项目,然后选择ho_prj项目.这样就解决编译出错的问题了.
建立hbm配置包:
建立一个Java类库项目,叫做hbm_prj,将hbm文件放进[源码]目录中.
进入原项目的属性窗口,选择打包页->添加项目,选择hbm_prj项目,回到属性窗口页面,将[WAR中的路径]改为/WEB-INF/.你也可以改为别的路径,但不能是/WEB-INF/lib/目录.另外,为了安全性,建议在WEB-INF路径下.
这里为什么要建两个项目,而不直接一个jar包打入实体类和hbm文件呢?因为在类装载时,web容器会将所有的lib目录下的jar包都载入,而Hibernate在读取hbm时,会再次装载jar包.这样就会导致Hibernate映射出现重复异常.因此,在这里将hbm再单独打一个jar包.并放在lib目录之外,就不会出现重复异常了.
注:这个现象应该是Hibernate的一个Bug.可能是Hibernate在读取jar包时,没有检查jar包是否已经被读取过了.
实践第二步:修改Hibernate配置
==============================
我这个项目是基于SSH的,因此,实际上是要修改spring配置文件,一般都叫applicationContext.xml.打开它.
找到Hibernate的配置部分.
<bean id="sessionFactory" lass="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingLocations">
<list>
<value>classpath:/com/myc/prj/*.hbm.xml</value>
</list>
</property>
........................
</bean>
这是我们通常的写法,不过这样是不能从jar包中读取数据的.需要加入下面的内容
<property name="mappingJarLocations">
<list>
<value>WEB-INF/hbm_prj.jar</value>
</list>
</property>
那么完整的内容就应该是:<bean id="sessionFactory" lass="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingJarLocations">
<list>
<value>WEB-INF/hbm_prj.jar</value>
</list>
</property>
<property name="mappingLocations">
<list>
<value>classpath*:/com/myc/prj/*.hbm.xml</value>
</list>
</property>
........................
</bean>
注意,classpath后面多加了一个*号.
实践第三步:运行:
==============================
将原项目[清理并生成]后点击运行(我个人的做法是先将服务器停止,然后清理并生成,最后直接运行服务器,这样要比运行快很多.)
现在项目应该可以正常运行了.
常见问题:
================================
1. Duplicate class/entity mapping问题:
检查是否将hbm_prj.jar放到WEB-INF/lib目录了.注意,如果不小心将hbm_prj项目做为库引入的话,IDE会自动将hbm_prj.jar放到lib目录中去.