Java/Hibernate - 在只读模式下不允许写操作 [英] Java / Hibernate - Write operations are not allowed in read-only mode

查看:24
本文介绍了Java/Hibernate - 在只读模式下不允许写操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近经常遇到一个令人讨厌的异常,在对 Google 和这个论坛进行了一些研究之后,我仍然没有找到可以解决我的问题的答案.

I've been having an annoying exception a lot lately, and after some research on Google and this forum I still haven't found an answer that could solve my problem.

事情就是这样 - 有时,我在尝试使用休眠更新或创建新对象时会收到以下错误:

Here's the thing - sometimes, I get the following error when trying to update or create a new object with 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)

真正奇怪的是,有时当使用方法 getHibernateTemplate().saveOrUpdate(object); 更新对象时它会工作,但有时使用相同的对象并调用相同的方法它不起作用,但它似乎首先取决于我如何获取对象.

What is really strange is that, sometimes when updating an object with the method getHibernateTemplate().saveOrUpdate(object); it will work, but sometimes with the same object and by calling the same method it doesn't work, but it seems to depend on how I get the object in the first place.

示例:假设我有一个包含 3 个字段的表:id、类型、长度.可能发生的情况是,如果我通过 id 获取对象并更新长度,那么它将起作用.如果我按类型获取它并更新长度,那么它将不起作用.所以到目前为止,我一直在做的事情是为了避免这个问题,是通过以后不会引起问题的方法来获取对象,但是尝试找到一种有效的方法变得越来越烦人.

Example: let's say I have a table with 3 fields: id, type, length. What can happen is that, if I get the object by the id and update the length, then it will work. If I get it by the type and update the length, then it won't work. So what I've been doing so far to avoid the problem is to fetch the object the method that does not cause a problem later, but this is becoming more and more annoying to try and find a way that works.

此外,现在我在尝试创建对象(但不是所有对象,仅在一个特定表上)时遇到此异常,并且找不到解决方法.我试图在事务中添加 @Transactional(readOnly = false) 但它没有改变任何东西,并且显示模式表明我无论如何都不是只读的.

Also, now I have this exception when trying to create an object (but not all of them, just on one specific table), and can't find a way for a workaround. And I tried to add @Transactional(readOnly = false) in the transaction but it didn't change anything, and displaying the mode was saying that I wasn't in read-only anyway.

有什么建议吗?

编辑 7 月 26 日:这里是一些与休眠相关的配置

Edit 26th of July: here's some configuration related to 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>

还有,如果可以的话

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

编辑 8 月 31 日:我的类中扩展 HibernateDaoSupport 的相关代码,用于保存对象是:

Edit 31st of August: The relevant code in my Class that extends HibernateDaoSupport, to save the objects is:

public void createObject(Object persisObj) {
    getHibernateTemplate().save(persisObj);
}

推荐答案

我从视图过滤器中更改了单个会话属性.问题已解决:

I changed the single session propery from view filter. Problem solved:

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

这篇关于Java/Hibernate - 在只读模式下不允许写操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆