论坛首页 Java版 Spring

有关OpenSessionInView模式的问题

浏览 11389 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2004-12-20
我模仿robbin的demo做了一个类似的demo,结构是struts+spring+hibernate。起初,我没有用OpenSessionInView模式,一切正常运行。等我加入了OpenSessionInView模式以后,出现了只能查询,不能进行save,update和delete操作的问题。

我看了一下OpenSessionInView的源码,发现它的getSession函数是这样的:
[code:1]
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.NEVER);
return session;
}
[/code:1]
默认情况下,把session的flushMode设置成为NEVER,而我save或者update时报的错也是NEVER这种模式只支持只读。

OpenSessionInView模式到底应该如何使用?或者在哪里配置呢?请用过的朋友指点。
   
时间:2004-12-20
不要使用singleSession:
	<filter>
	    <filter-name>opensession</filter-name>
	    <filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>false</param-value>
        </init-param>
	</filter>


详细的说明,看OpenSessionInViewFilter的文档。
   
0 请登录后投票
时间:2004-12-20
刚刚看了OpenSessionInView的详细说明,想来结贴,没想到还是被readonly先回答了,惭愧惭愧,以后一定更加仔细看注释和文档!
   
0 请登录后投票
时间:2004-12-20
在目前的使用中,我采用了readonly的方法,把singleSession设置成为false。但是出现了以下问题:
在带有父子关系的一个应用中,我首先load出所有的父亲,显示在result.jsp中,然后,我选中其中的一个父亲,点击删除,调用某个struts的DeleteParentAction,此时,却报错说:由于有多个session,无法绑定正确的session。
这种情况应该如何处理?
   
0 请登录后投票
时间:2004-12-21
没有遇到过,弄个简单的测试代码出来瞅瞅。
   
0 请登录后投票
时间:2004-12-21
早上写了简单的测试,还是会遇到这样的问题。
环境:Tomcat5,mysql4.0,结构:struts+spring+hibernate
数据库表:parent( id, name) child(id, name, parent_id)构成父子关系。
测试的DAO如下:
[code:1]

public void saveOrUpdateParent(Parent p) {
getHibernateTemplate().saveOrUpdate(p);
}

public void deleteParentById(Class persistentClass, Serializable id) {
getHibernateTemplate().delete(getObjectById(persistentClass, id));
}

public Object getParentById(Class persistentClass, Serializable id) {
return getHibernateTemplate().get(persistentClass, id);
}

public List getAllParent(Class persistentClass) {
return getHibernateTemplate().loadAll(persistentClass);
}

public void deleteParent(Serializable id) {
getHibernateTemplate().delete("FROM parent in class com.joa.po.Parent WHERE parent.id =" + id);
}

public int getParentCount() {
Iterator iter = getHibernateTemplate().iterate("SELECT count(*) FROM parent in class com.joa.po.Parent");
return ((Integer)iter.next()).intValue();
}
[/code:1]

applicationContext.xml大致如下:
[code:1]
<beans>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/jdbc.properties</value>
</list>
</property>
</bean>

<!-- dataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>${jdbc.driverClassName}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>

<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<!-- Add list of .hbm.xml files here -->
<value>com/joa/po/Parent.hbm.xml</value>
<value>com/joa/po/Child.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.Provider</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>


<!-- Add DAOs here -->
<bean id="parentDAO" class="com.joa.dao.impl.ParentDAOImpl">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>


<!-- Add Managers here -->
<bean id="parentServiceTarget" class="com.joa.service.impl.ParentServiceImpl">
<property name="parentDAO"><ref local="parentDAO"/></property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>

<bean id="service" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<ref local="parentServiceTarget"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>


</beans>

测试的结果大概是这样:
1、在使用OpenSessionInView模式的情况下,调用deleteParentById这个函数,测试不通过,报的错是:有两个session存在,无法绑定。但是调用deleteParent(Serializable id) 却是通过的,可以正确删除。
2、在使用OpenSessionInView模式的情况下,调用getParentCount() 这个函数可以正确得到结果,但是如果在不用OpenSessionInView模式的情况下,调用这个函数,会报一个lazy problem的错。我不明白的是,这个地方难道用到lazy了嘛?[/code:1]
   
0 请登录后投票
时间:2004-12-22
无法重现错误......
无论用singleSession true/false,都从来没有遇到这样的错误......
   
0 请登录后投票
时间:2004-12-22
引用
1、在使用OpenSessionInView模式的情况下,调用deleteParentById这个函数,测试不通过,报的错是:有两个session存在,无法绑定。但是调用deleteParent(Serializable id) 却是通过的,可以正确删除。
2、在使用OpenSessionInView模式的情况下,调用getParentCount() 这个函数可以正确得到结果,但是如果在不用OpenSessionInView模式的情况下,调用这个函数,会报一个lazy problem的错。我不明白的是,这个地方难道用到lazy了嘛?

把exception的信息贴出来!
   
0 请登录后投票
时间:2004-12-22
我明天把整个eclipse的源文件整理一下上传吧,我也觉得很奇怪,尤其是那个iterator的问题,也太怪了。
   
0 请登录后投票
时间:2004-12-23
你是不是调用了getHibernateTemplate().saveOrUpdate(obj)?

新版本的spring和新版本的hibernate配合,使用这个方法,如果有lazy load的collection,那么就会有你说的第一个问题。

解决方法是:
1. 等待spring的下一个release,已经有人提交这个bug了。
或者
2. 改成分开使用save或者update
   
0 请登录后投票
论坛首页 Java版 Spring

跳转论坛:
JavaEye推荐