小编典典

Java / Hibernate-在只读模式下不允许写操作

spring

当我尝试使用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);会起作用,但是有时使用相同的对象并通过调用相同的方法却无法起作用,但这似乎取决于我如何在对象中获取对象。第一名。

示例:假设我有一个包含3个字段的表:id,类型,长度。可能发生的是,如果我通过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>

另外,如果它可以帮助

<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,用于保存对象的相关代码是:

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

阅读 837

收藏
2020-04-13

共2个答案

小编典典

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

  <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>
2020-04-13
小编典典

使用Spring OpenSessionInViewFilter并尝试在Spring管理的事务之外执行持久性操作时,通常会看到该错误消息。过滤器将会话设置为FlushMode.NEVER / MANUAL(取决于你使用的Spring和Hibernate的版本-它们大致等效)。当Spring事务机制开始事务时,它将刷新模式更改为“ COMMIT”。事务完成后,它会根据需要将其设置回NEVER / MANUAL。如果你绝对确定如果这没有发生,那么下一个最可能的罪魁祸首就是会话的非线程安全使用。hibernate会话只能在一个线程中使用。如果它在线程之间交叉,则会发生各种混乱。请注意,从Hibernate加载的实体可以保存对其加载的Session的引用,因此跨线程传递该实体也可以导致从另一个线程访问Session。

2020-04-13