`

为何OpenSessionInView不能同时保存和删除

阅读更多

代码:


    <filter>
        <filter-name>opensession</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>



写了个保存的代码测试了一下,报如下的错误:

代码:


org.springframework.dao.InvalidDataAccessApiUsageException: Write operations
are not allowed in read-only mode (FlushMode.NEVER) - turn your Session
into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
   at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1076)
   at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:616)
   at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)
   at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:614)
   at com.phopesoft.security.service.impl.UserServiceImpl.addUser(UserServiceImpl.java:40)
   at com.phopesoft.security.web.UserAction.add(UserAction.java:52)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at com.opensymphony.xwork.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:365)
................



javaeye中搜索了一下,发现了Readonly的帖子,web.xml修改为如下:

代码:


    <filter>
        <filter-name>opensession</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>false</param-value>
        </init-param>
    </filter>



保存的代码顺利通过测试,但是删除的代码却不能通过了.出现如下的错误:

代码:


org.hibernate.HibernateException: Illegal attempt to associate a collection
with two open sessions
   at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
   at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
   at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
   at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
   at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:72)
   at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:790)
   at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:768)
   at org.springframework.orm.hibernate3.HibernateTemplate$25.doInHibernate(HibernateTemplate.java:772)
   at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:766)
   at org.springframework.orm.hibernate3.HibernateTemplate.delete(HibernateTemplate.java:762)




 

****************************************

 

首先要说明一下Open Session in View的作用,就是允许在每次的整个request的过程中使用同一个hibernate session,可以在这个request
何时期lazy loading数据。
如果是singleSession=false的话,就不会在每次的整个request的过程中使用同一个hibernate session,而是每个数据访问都会产生各自的seesion,等于没有Open Session in View.
OpenSessionInViewFilter
默认是不会对session 进行flush,并且flush mode never

代码:

   protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
      Session session = SessionFactoryUtils.getSession(sessionFactory, true);
      session.setFlushMode(FlushMode.NEVER);
      return session;
   }

getSession的方式就知道,flush mode 设为FlushMode.NEVER,这样就算是commit的时候也不会session flush,
如果想在完成request过程中更新数据的话, 那就需要先把flush model设为FlushMode.AUTO,再在更新完数据后flush.

 

********************************

 

,是事务的问题,感谢差沙也感谢cac的回复.

OpenSessionInView
默认的FlushMode

代码:


FlushMode.NEVER



可以采用在写保存更新删除代码的时候手动更改FlushMode

代码:


        this.getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException {
                session.setFlushMode(FlushMode.AUTO);
                session.save(user);
                session.flush();
                return null;
            }
        });



但是这样做太繁琐了,第二种方式是采用spring的事务声明

代码:


    <bean id="baseTransaction" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
          abstract="true">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="proxyTargetClass" value="true"/>
        <property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="add*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

<o:p> </o:p>

代码:


    <bean id="userService" parent="baseTransaction">
        <property name="target">
            <bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
        </property>
    </bean>



 

来源:http://spring.jactiongroup.net/viewtopic.php?p=5791

谢谢各位<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape id="_x0000_i1025" style="WIDTH: 11.25pt; HEIGHT: 11.25pt" type="#_x0000_t75" alt="Smile"><v:imagedata src="file:///C:\DOCUME~1\Q\LOCALS~1\Temp\msohtml1\01\clip_image001.gif" o:href="http://spring.jactiongroup.net/images/smiles/icon_smile.gif"></v:imagedata></v:shape>
同样在论坛里面搜索到遇到这个问题的朋友,回帖说去掉singleSession!

迷惑了
<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype><v:shape id="_x0000_i1025" style="WIDTH: 11.25pt; HEIGHT: 11.25pt" type="#_x0000_t75" alt="Sad"><v:imagedata src="file:///C:\DOCUME~1\Q\LOCALS~1\Temp\msohtml1\01\clip_image001.gif" o:href="http://spring.jactiongroup.net/images/smiles/icon_sad.gif"></v:imagedata></v:shape>
分享到:
评论

相关推荐

    Spring hibernate opensessioninview

    ### Spring + Hibernate OpenSessionInView 模式的理解和应用 在Java Web开发中,Spring与Hibernate作为两个重要的框架,经常被一起使用来实现业务逻辑与数据持久化的处理。而在使用这两个框架时,为了更好地管理...

    Struts Spring Hibernate 整合 OpenSessionInView 例子

    为了练手培训,给大家准备的 Open Session In View 的简单例子,纯代码,大家可以参考,其中主要说了六部分内容: 1.通过接口编程 2.通过spring注入dao到 action 3.通过 open session in view filter 支持 延迟加载...

    OpenSessionInView项目整合jar包

    在Java Web开发中,OpenSessionInView(OSIV)模式是一种常见的解决数据持久化问题的设计模式,主要用于Spring框架与Hibernate等...同时,注意合理配置和使用,以防止长时间打开的Session导致内存泄漏或其他潜在问题。

    Spring提供的CharacterEncoding和OpenSessionInView功能

    Spring框架是Java开发中不可或缺的一部分,它为开发者提供了丰富的功能,包括依赖注入、面向切面编程、事务管理等。在处理Web应用时,Spring提供了一些关键特性,如`CharacterEncodingFilter`和`...

    第30讲--Spring提供的CharacterEncoding和OpenSessionInView功能

    同时,需要注意的是,OpenSessionInView模式虽然方便,但也会带来潜在的问题,如事务边界不清晰和会话泄漏。因此,在实际应用中,应结合具体需求谨慎使用,并考虑使用更现代的解决方案,如Spring Data JPA的...

    Open_Session_In_View详解.doc

    这样做的好处在于,可以确保在整个请求处理过程中session始终处于可用状态,使得在视图(View)层也能利用懒加载特性。 实现这一机制的方式有两种: 1. **OpenSessionInViewInterceptor**:通过拦截器实现。在Spring...

    SSH项目整合示例【OpenSessionInView】所用到的jar包

    SSH是Java Web开发中的一个流行框架组合,由Struts、Hibernate和Spring三个组件构成。这个框架集成提供了模型-视图-控制器(MVC)架构,数据持久化,以及依赖注入和事务管理等功能,大大简化了企业级应用的开发工作...

    spring中lazy=“true”的正常读取关联表(用opensessioninview)

    然而,单纯地使用 `lazy="true"` 有时并不能很好地工作,尤其是在Web应用中。由于HTTP请求的无状态性,每次请求结束后,Session就会关闭,导致在后续的操作中试图访问懒加载属性时会出现“Session已关闭”的异常。...

    MyContextLoaderPlugIn.jar

    和Spring中OpenSessionInView由于org.springframework.web.struts.ContextLoaderPlugIn中保存同一个对象的名不同导致openSessionInView失效 稍微修改后在struts-config.xml中使用MyContextLoaderPlugIn.jar包中...

    关于OpenSessionInViewFilter的学习

    1. **事务管理**:OpenSessionInViewFilter并不负责事务的开启和提交,通常需要配合Spring的TransactionProxyFactoryBean或者@Transactional注解来管理事务。 2. **性能影响**:由于延长了Session的生命周期,可能...

    Java框架面试题

    事务隔离级别有五种,从低到高分别为DEFAULT、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ和SERIALIZABLE,每种级别都对应不同的并发控制策略。 9. **Hibernate的update()与saveOrUpdate()**:`update()`...

    TSH练习例子

    FreeRoller和Atlassian Confluence等应用采用OpenSessionInView模式,尽管存在争议,但在某些场景下能有效提升效率。 ### Domain Logic与Use Case Logic 文档提到区分Domain Logic(领域逻辑)和Use Case Logic...

    spring+spingmvc+hibernate整合总结

    OpenSessionInView过滤器在Web请求的整个生命周期内保持一个Hibernate Session,使得在视图渲染阶段也能访问到数据库对象,避免了懒加载异常。 五、配置文件 1. `jdbc.properties`:存放数据库连接信息,如URL、...

    SSH面试总结(非常全)

    通过`HibernateTemplate`类,Spring简化了Hibernate的使用,提供了包括保存、更新、删除、查询等在内的常用操作。当使用`getHibernateTemplate()`方法时,Spring会自动管理事务,无需显式提交或回滚,提高了开发效率...

    struts+spring+hibernate面试题.doc

    在Spring中使用Hibernate时,可以利用`HibernateTemplate`简化常见的CRUD操作,同时Spring的事务管理器能无缝集成Hibernate的事务处理,提供统一的事务控制。通过Spring配置,可以轻松管理Hibernate的SessionFactory...

    收集的struts+spring+hibernate面试题借鉴.pdf

    事务隔离级别有:DEFAULT(遵循数据库默认)、READ_UNCOMMITTED(可能出现脏读、不可重复读和幻影读)、READ_COMMITTED(可能出现不可重复读和幻影读)、REPEATABLE_READ(可能出现幻影读)和SERIALIZABLE(最安全但...

    搭建SSH框架总结.doc

    8. **设置字符编码过滤器**:为了确保请求和响应的正确编码,需要在`web.xml`中添加一个自定义的Filter,如`SetEncodingFilters`,以设置请求和响应的字符编码为UTF-8或其他指定的编码格式。 在实际开发中,SSH框架...

    struts+hibernate,spring面试题

    在Spring中使用Hibernate,通常需要配置SessionFactory、TransactionManager,使用HibernateTemplate或SessionFactoryBean进行数据访问,同时结合Spring的声明式事务管理,确保事务的正确性和一致性。 以上是对SSH...

    SSH整合示例项目 hibernate5.2.3+struts2.5.2+spring4.3.3.zip

    这个项目是一个基于最新版本SSH的示例应用,具体为Hibernate 5.2.3、Struts 2.5.2和Spring 4.3.3的集成。以下是关于SSH整合及其相关知识点的详细说明: **1. Spring框架(4.3.3)** Spring是一个开源的Java平台,它...

    HibernateSpring多数据库解决方案.doc

    虽然这里的配置没有完整展示,但通常我们会为每个`SessionFactory`创建一个`JdbcTemplate`实例,以便在不使用Hibernate的情况下执行SQL操作。 总结起来,这个多数据库解决方案利用Spring的IoC容器管理和配置了多个...

Global site tag (gtag.js) - Google Analytics