Gui*_*ume 15 java spring hibernate readonly
我最近经常遇到一个烦人的例外,经过对谷歌和这个论坛的一些研究后,我仍然没有找到可以解决我的问题的答案.
这是事情 - 有时,我尝试使用hibernate更新或创建一个新对象时出现以下错误:
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.
at org.springframework.orm.hibernate3.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1186)
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:696)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:694)
Run Code Online (Sandbox Code Playgroud)
真正奇怪的是,有时用方法更新对象时getHibernateTemplate().saveOrUpdate(object);它会起作用,但有时候使用相同的对象并通过调用相同的方法它不起作用,但它似乎取决于我如何获得对象第一名.
示例:假设我有一个包含3个字段的表:id,type,length.可能发生的是,如果我通过id获取对象并更新长度,那么它将起作用.如果我按类型获取并更新长度,那么它将无法工作.所以到目前为止我一直在做的是避免这个问题,就是获取对象后面不会引起问题的方法,但是尝试找到一种有效的方法会变得越来越烦人.
此外,现在我在尝试创建一个对象(但不是所有对象,仅在一个特定的表上)时遇到此异常,并且无法找到解决方法的方法.我试图@Transactional(readOnly = false)在事务中添加但它没有改变任何东西,显示模式就是说我不是只读的.
有什么建议?
编辑7月26日:这里有一些与hibernate相关的配置
<property name="hibernateProperties">
<props>
<prop key="jdbc.fetch_size">20</prop>
<prop key="jdbc.batch_size">25</prop>
<prop key="cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="connection.autoReconnect">true</prop>
<prop key="connection.autoReconnectForPools">true</prop>
<prop key="connection.is-connection-validation-required">true</prop>
</props>
</property>
Run Code Online (Sandbox Code Playgroud)
如果它可以帮助
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="execute*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
Run Code Online (Sandbox Code Playgroud)
编辑8月31日:HibernateDaoSupport为了保存对象,我的类中扩展的相关代码是:
public void createObject(Object persisObj) {
getHibernateTemplate().save(persisObj);
}
Run Code Online (Sandbox Code Playgroud)
Rya*_*art 13
当使用Spring OpenSessionInViewFilter并尝试在Spring管理的事务之外执行持久性操作时,通常会看到该错误消息.过滤器将会话设置为FlushMode.NEVER/MANUAL(取决于您使用的Spring和Hibernate的版本 - 它们大致相当).当Spring事务机制开始一个事务时,它将刷新模式更改为"COMMIT".事务完成后,它会根据需要将其设置为NEVER/MANUAL.如果您完全确定没有发生这种情况,那么下一个最可能的罪魁祸首就是非线程安全地使用Session.Hibernate Session必须只在一个线程中使用.如果它穿过线程之间,就会发生各种混乱.请注意,从Hibernate加载的实体可以保存对加载它的Session的引用,因此跨线程处理实体也可以导致从另一个线程访问Session.
我从视图过滤器更改了单个会话属性.问题解决了:
<filter>
<filter-name>hibernateFilter</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>
Run Code Online (Sandbox Code Playgroud)
我也偶然发现了这一点.我需要将Spring的OpenSessionInViewFilter中的刷新模式更改为手动,突然我开始得到这个异常.我发现问题是在没有注释为@Transactional的方法中出现问题,所以我猜Spring会隐式地将所有数据访问代码视为只读方法.注释该方法解决了这个问题.
另一种方法是在HibernateTemplate对象上调用setCheckWriteOperations方法.
小智 5
在应用程序上下文中使用bean下面的HibernateTemplate.
<bean id="template" class="org.springframework.orm.hibernate4.HibernateTemplate">
<property name="sessionFactory" ref="mysessionFactory"></property>
<property name="checkWriteOperations" value="false"></property>
</bean>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
52268 次 |
| 最近记录: |