论坛首页 Java企业应用论坛

有关OpenSessionInView模式的问题

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

我看了一下OpenSessionInView的源码,发现它的getSession函数是这样的:
protected Session getSession(SessionFactory sessionFactory);
			throws DataAccessResourceFailureException {
		Session session = SessionFactoryUtils.getSession(sessionFactory, true);;
		session.setFlushMode(FlushMode.NEVER);;
		return session;
	}

默认情况下,把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如下:

	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();;
	}


applicationContext.xml大致如下:
<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了嘛?
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企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics