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 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中:
<!-- 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
<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>