Spring and Hibernate suddenly set the transaction to readonly Spring and Hibernate suddenly set the transaction to readonly spring spring

Spring and Hibernate suddenly set the transaction to readonly


This exception comes from the following code in Spring's HibernateTemplate class:

protected void checkWriteOperationAllowed(Session session) throws InvalidDataAccessApiUsageException {    if (isCheckWriteOperations() && getFlushMode() != FLUSH_EAGER &&            session.getFlushMode().lessThan(FlushMode.COMMIT)) {        throw new 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.");    }}

The rationale for this check is explained as:

This is a new consistency check introduced in Spring 1.1.

Invoking HibernateTemplate's save/update/delete methods on a Spring-managed Session in FlushMode.NEVER is potentially dangerous: It means that you are:

  • either doing this in a Spring-managed read-only transaction, which will never flush the Hibernate Session, i.e. never flush your save/update/delete calls. The new check makes you aware that you won't persist your changes in that situation.

  • or working with some other thread-bound Session in FlushMode.NEVER, for example the OpenSessionInViewFilter. If you're overriding closeSession there to flush after view rendering, you should override getSession too, setting the Session to FlushMode.AUTO.

I strongly recommend against the latter, though. If you're using OpenSessionInViewFilter, combine it with middle tier transactions rather than let the filter flush at request completion.

Does any of this ring a bell?

It is possible that there is some bug in the your code or in Spring ORM. To disable this check you can call setCheckWriteOperations(false).


aseesing, i check your configuration. in spring context part, you use

<!-- other methods use the default transaction settings (see below) -->   <tx:method name="*" read-only="true" propagation="REQUIRED" />

usually, only some accesses are read-only types, such as get/find/query, etc. i suggest use

<!--default is required transaction--><tx:method name="*"/>

another thing is, do you use opensessioninview pattern? flush mode could be set in opensessioninview properly. you can use filter in web.xml or use spring interceptor in application context config.


in your web.xml put :

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