【发布时间】:2014-10-26 12:52:33
【问题描述】:
我正在尝试使用 Hibernate 4.3.5.Final 和 Spring 4.0.6 升级我们的应用程序。在我的应用程序中进行数据库写入操作的任何地方都会出现如下错误:
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
at org.springframework.orm.hibernate4.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1135)
at org.springframework.orm.hibernate4.HibernateTemplate$26.doInHibernate(HibernateTemplate.java:826)
at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:340)
at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
at org.springframework.orm.hibernate4.HibernateTemplate.deleteAll(HibernateTemplate.java:823)
...
以下是我对 sessionFactory 和 transactionManager 的 spring 配置:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>com/mycompany/Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
1:
为了全局设置flushMode以使应用程序以与以前相同的方式工作,我需要将flushMode全局设置为AUTO,因此我不想使用@Transactional(readOnly = false)方法。
2:
在下面的帖子中,有人建议将 singleSession 设置为 false, Java / Hibernate - Write operations are not allowed in read-only mode
Spring 文档建议指定 "singleSession"="false" 有副作用: http://docs.spring.io/spring/docs/4.0.6.RELEASE/javadoc-api/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.html
3:
我在 web.xml 中看到了很多类似下面的建议,它允许你拦截 hibernate3 会话并提供一个版本的会话,例如冲洗模式。自动。但是,当您使用 org.springframework.orm.hibernate4.support.OpenSessionInViewFilter 时,这在 hibernate 4 中不起作用。
<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>
4:
下面建议的方法是使用 JPA 事务管理器,它遵循 HibernateJpaDialect 的复杂重新实现。我目前没有使用 JPA,而且这种方法似乎不够简单。 How do I set flush mode to "COMMIT" in my configuration files?
5:
我尝试在我的 spring 配置中包含以下内容(遵循Spring ORM 4.0.5 and Hibernate 4.3.5 - Cant save to database 的建议), 它似乎不起作用,人们建议使用 web.xml 方法: Spring and Hibernate suddenly set the transaction to readonly
<tx:advice id="transactionAdvice" transaction-manager="transactionManager" >
<tx:attributes>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
问题:
谁能建议一种简单的方法来允许为 Hibernate 4.3.5.Final 和 Spring 4.0.6 设置 FlushMode?p>
【问题讨论】:
-
如果未设置刷新模式,我怀疑有错误或缺少事务管理。您拥有
HibernateTransactionManager的事实并不意味着您已正确设置了 tx。此外,仅添加<tx:advice />而不添加<aop:config />来应用它几乎是没有用的。 -
@M.Deinum 感谢您的评论。就我而言,我需要在应用程序中镜像以前的行为,即使用 FlashMode.AUTO(它是旧 Hibernate 版本 3.0.5 的默认设置)。您的回答使我能够对更清洁的解决方案进行进一步调查(如果全局设置只读为 false 满足我们应用程序的需要)。
标签: java spring hibernate hibernate-4.x spring-4