问题描述:在使用Hibernate和Struts是经常会遇到如下BUG:
org.apache.struts2.json.JSONException: org.apache.struts2
.json.JSONException: org.hibernate.LazyInitializationException:
failed to lazily initialize a collectionof role: blank.domain.Route.stopRoutes, could not initialize proxy - no Session
解决方案:
方法一、在web.xml中添加Session过滤器的配置
<!-- 延迟关闭session 的顺序位于struts2过滤之上 否则延迟关闭session不起作用 -->
<filter>
<filter-name>opensession</filter-name>
<filter-class>
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>opensession</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
由于org.springframework.orm.hibernate4.support.OpenSessionInViewFilter这个类中指定sessionFactoryBeanName的值为“sessionFactory”
所以,在Spring配置文件中,与SessionFactory相关的配置需要把名称改为“sessionFactory”,否则会报找不到sessionFactory的BUG。
具体如下:
<!-- SessionFactory工厂 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<!-- 配置HibernateTemplate模板 -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置HibernateDaoSupport -->
<bean id="hibernateDaoSupport"
class="org.springframework.orm.hibernate4.support.HibernateDaoSupport"
abstract="true">
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>
<!-- Hinernate的事务管理器 -->
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
方法二、在Hibernate的*.hbm.xml配置文件中将lazy属性设置为false(不推荐)。
案例:
stopRoute.hbm.xml中
<many-to-one name="route" class="Route" cascade="save-update" fetch="join" lazy="false">
<column name="rid" />
</many-to-one>
<many-to-one name="stop" class="Stop" cascade="save-update" fetch="join" lazy="false">
<column name="sid" />
</many-to-one>
Route.hbm.xml中
<set name="stopRoutes" inverse="true" cascade="delete" lazy="false">
<key>
<column name="rid" />
</key>
<one-to-many class="StopRoute" />
</set>