`

为何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>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics