首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

spring和hibernate 主键表对象,一对多 set,出现session关闭的有关问题

2012-01-08 
spring和hibernate主键表对象,一对多 set,出现session关闭的问题这个是主键表:hibernate-mappingclass

spring和hibernate 主键表对象,一对多 set,出现session关闭的问题
这个是主键表:
<hibernate-mapping>
  <class name="entity.Type" table="type" schema="dbo" catalog="house">//房屋类型
  <id name="id" type="java.lang.Integer">
  <column name="id" />
  <generator class="native" />
  </id>
  <property name="name" type="java.lang.String">
  <column name="name" length="50" not-null="true" />
  </property>
  <set name="houses" inverse="true" lazy="true">
  <key>
  <column name="typeId" not-null="true" />
  </key>
  <one-to-many class="entity.House" />//房屋
  </set>
  </class>
</hibernate-mapping>

在lazy=true 方式下,程序会报错,错误信息是:Error marshalling entity.Type :failed to lazily initialize a collection of role: entity.Type.houses,no session or session was closed.

我查了一下解决办法,最简单的解决办法是把set部分的lazy=true修改为false,但是据说这样会影响效率。

所以,我要请教,在lazy=true的情况下,如何纠正这个错误。

我给出applicationContext.xml的内容:
----------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.microsoft.jdbc.sqlserver.SQLServerDriver">
</property>
<property name="url"
value="jdbc:microsoft:sqlserver://127.0.0.1:1433">
</property>
<property name="username" value="sa"></property>
</bean>
<!--用于大文本-->
<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<!--用于大文本-->
<property name="lobHandler" ref="defaultLobHandler" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>entity/Region.hbm.xml</value>
<value>entity/Type.hbm.xml</value>
<value>entity/Patch.hbm.xml</value>
<value>entity/Picture.hbm.xml</value>
<value>entity/House.hbm.xml</value>
<value>entity/Corporation.hbm.xml</value>
<value>entity/Test.hbm.xml</value></list>
</property></bean>
<!--用于事务-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
<property name="sessionFactory"> 
  <ref local="sessionFactory"/> 
</property> 


</bean>
<!--配置声明式事务代理工厂--> 
<bean id="transactionProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
  <ref local="transactionManager"/>
</property>
<property name="transactionAttributes">
  <props>
  <prop key="add*">
  PROPAGATION_REQUIRED
  </prop>
  <prop key="*">
  PROPAGATION_REQUIRED
  </prop>
  </props>
</property>
</bean>
  。。。
-------------------------------------

谢谢了

[解决办法]
看OpenSessionInView 
百度一下OpenSessionInView 

XML code
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">    <!-- *************************************************************************start******** -->    <display-name>demo</display-name>    <!-- **********************************************************************context-param*********** -->    <!--spring配置-->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath*:appContext*.xml</param-value>    </context-param>    <!-- ***********************************************************************listener********** -->    <!--spring配置-->    <listener>        <listener-class>            org.springframework.web.context.ContextLoaderListener        </listener-class>    </listener>    <!-- **********************************************************************filter*********** -->    <!-- 中文过滤器 -->    <filter>        <filter-name>Set Character Encoding</filter-name>        <filter-class>com.syj.util.SetCharacterEncodingFilter</filter-class>        <init-param>            <param-name>encoding</param-name>            <param-value>GBK</param-value>        </init-param>    </filter>    <!-- hibernate3 OpenSessionInView 模式 -->    <filter>        <filter-name>OpenSessionInViewFilter</filter-name>        <filter-class>            com.syj.util.OpenSessionInViewFilter        </filter-class>    </filter>    <!--struct配置 -->    <filter>        <filter-name>Struts2</filter-name>        <filter-class>            org.apache.struts2.dispatcher.FilterDispatcher        </filter-class>    </filter>    <!-- **********************************************************************filter-mapping*********** -->    <!-- 中文过滤器 -->    <filter-mapping>        <filter-name>Set Character Encoding</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- hibernate3 OpenSessionInView 模式 注意:一定配置struct mapping的前面-->    <filter-mapping>        <filter-name>OpenSessionInViewFilter</filter-name>        <url-pattern>*.do</url-pattern>    </filter-mapping>    <!--struct配置 注意:一定配置OpenSessionInView mapping的后面-->    <filter-mapping>        <filter-name>Struts2</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <!-- ************************************************************************servlet********* -->    <!-- 负责系统初始化的启动Servlet -->    <servlet>        <servlet-name>initServlet</servlet-name>        <servlet-class>com.syj.action.InitServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>    <!-- 配置图形码 -->    <servlet>        <servlet-name>codeFact</servlet-name>        <servlet-class>com.syj.util.CodeFact</servlet-class>    </servlet>    <!-- jfreechart显示图表 -->    <servlet>        <servlet-name>DisplayChart</servlet-name>        <servlet-class>            org.jfree.chart.servlet.DisplayChart        </servlet-class>    </servlet>    <!-- ************************************************************************servlet-mapping********* -->    <!-- 负责系统初始化的启动Servlet -->    <servlet-mapping>        <servlet-name>initServlet</servlet-name>        <url-pattern>/initServlet</url-pattern>    </servlet-mapping>    <!-- 配置图形码 -->    <servlet-mapping>        <servlet-name>codeFact</servlet-name>        <url-pattern>/codeFact</url-pattern>    </servlet-mapping>    <!-- jfreechart显示图表 -->    <servlet-mapping>        <servlet-name>DisplayChart</servlet-name>        <url-pattern>/servlet/DisplayChart</url-pattern>    </servlet-mapping>    <!-- *************************************************************************jsp-config******** -->    <jsp-config>        <!--syj标签库配置-->        <taglib>            <taglib-uri>syj.tld</taglib-uri>            <taglib-location>/WEB-INF/syj.tld</taglib-location>        </taglib>    </jsp-config>    <!-- *************************************************************************end******** --></web-app> 


[解决办法]
Spring对声明事务的配置方法有2种。一个是楼主的方法。一种是用注释的方式。相对来说。注释方式更加自由。使用注释方式配置声明事务的方法在spring的referance中有详细的说明。lz可以去看下。

对于spring与hibernate整合。一般会将session与事务都交给spring去处理。除非一些必须自己去控制的事务。

附:注释方式配置声明事务的一个简单的例子。例子是jpa的。楼主照自己的更改。
applicationContext中:

XML code
<!-- JPA Transaction manager :JPA事务控制设置-->    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">        <property name="entityManagerFactory" ref="entityManagerFactory"/>        <property name="dataSource" ref="dataSource"/>    </bean>        <!-- TransAction Manager :文件配置声明事务管理 -->    <!--     <aop:config>        <aop:pointcut id="crudMethods" expression="execution(* com.ssh.service.*.*(..))"/>        <aop:advisor advice-ref="txAdvice" pointcut-ref="crudMethods"/>    </aop:config>         <tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="save" propagation="REQUIRED"/>            <tx:method name="update" propagation="REQUIRED"/>            <tx:method name="delete" propagation="REQUIRED"/>        </tx:attributes>    </tx:advice>     -->        <!-- TransAction Manager :注释配置声明事务管理 -->    <tx:annotation-driven transaction-manager="transactionManager"/>
[解决办法]
我最近也遇到这个问题,使用OpenSessionInView 性能好点,还是不考虑表和表之间的关联,每个实体写一个独立的 Service 类 然后通过自己写HQL 来是实现 相互关联的查找,不知道哪个性能好点,哪个更快点,OpenSessionInView,意味着Session在一段时间不关闭,对性能也有影响把。
[解决办法]
如果底层用hibernate来实现,你可以在web.xml里加上下面一段代码来控制session
OpenSessionInView 
Java code
<filter>        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>        <filter-class>            org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter        </filter-class>    </filter>    <filter-mapping>        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping> 

热点排行