1. 程式人生 > >InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEV

InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEV

錯誤截圖:
不能在只讀模式下進行寫操作
錯誤描述:
org.springframework.dao.InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction definition.

嘗試了以下三種方法
1、修改web.xml的配置,新增:flushMode為true

 <filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
      <param-name>sessionFactoryBeanName</param-name>
      <param-value
>mySessionFactory</param-value> </init-param> <init-param> <param-name> flushMode </param-name <param-value>AUTO</param-value> </init-param> </filter>

2、或者在spring_hibernate_cfg.xml配置檔案中設定read-only=”false”

<aop:config
>
<aop:pointcut id="bussinessService" expression="execution(* com.fan.service.base.*.*(..))" /> <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="false" propagation="NOT_SUPPORTED"/> <tx:method name="find*" read-only="false" propagation="NOT_SUPPORTED"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>

3、或者在BaseDao的相應方法處新增

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW )

均沒有解決該問題,如果專案較大的話,改配置檔案影響很大,不建議用修改配置檔案的方式進行處理,該問題最後找到的原因是:
在getXX()方法中呼叫了saveXX()方法,因為上層方法getXX()是隻讀的,所以在方法體內的方法都預設是隻讀的,即使saveXX()不是隻讀的也無效。
修改方式:將saveXX()的所有上層方法都修改為spring配置檔案中擁有read-only=”false”方法名開頭,例如:
配置檔案:

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>     
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="check*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="exchange*" propagation="REQUIRED" />           
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>

則將方法getXX()更改為exchangeXX()就可以解決這個問題。