Spring and Hibernate suddenly set the transaction to readonly

后端 未结 7 1148
春和景丽
春和景丽 2021-01-04 08:20

We have an application running on JBoss 4.2.3, using Spring 2.5.2 and Hibernate 3.2.6.ga. This is running on Linux JEE01 2.6.16.60-0.54.5-smp, using its own user. Writing to

7条回答
  •  走了就别回头了
    2021-01-04 09:12

    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).

提交回复
热议问题