首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Grails 2 StaleObjectStateException

Grails 2 StaleObjectStateException
EN

Stack Overflow用户
提问于 2015-09-03 22:14:45
回答 1查看 492关注 0票数 0

-更新:原来我们根本无法更新任何域对象。我们创建了非常简单的域/服务/控制器组合,但仍然得到StaleObjectStateException:行被另一个事务更新或删除(或者未保存的值映射不正确):com.sra.cgms.test.TestDomain#1是我们的域类。

代码语言:javascript
复制
class TestDomain {

    static mapping = {
         table name:'TEST_DOMAIN', schema:'cgms'
         id generator:'identity', column:'id', sqlType: 'int'
    }

    String someVal

    static constraints = {

        someVal(nullable: true)
    }
}

这是我们的服务班:

代码语言:javascript
复制
class TestService {

    public void updateDomain(int domainId) {
        TestDomain testDomain = TestDomain.get(1)
        testDomain.someVal = "updated Val"
        testDomain.save(flush: true, failOnError: true)
    }
}

这里是我们的控制器:

代码语言:javascript
复制
class TestController {

    def testService


    def updateData() {

        testService.updateDomain(1);

        render "Data updated"
    }
}

另外,当我们尝试从Grails控制台调用testService.updateDomain(1)时,它没有出现问题。

-最新情况

希望Groovy/Grails项目中的人以前遇到过这种(奇怪的)行为:

我们正在尝试将当前的Grails1.3.7版本升级到Grails2.4.5,并在一些地方获得StaleObjectStateException (提交表单时)。

这些消息通常如下所示:

类的com.package.workflow.WorkflowTaskHistory#212430对象,标识符为212430:乐观锁定失败;嵌套异常为org.hibernate.StaleObjectStateException:行被另一个事务更新或删除(或未保存的值映射不正确):

我们的环境配置是:

  • Groovy 2.3、Grails 2.4.5、Hibernate 4.3.8.1 (也尝试了3.6.10.18)、Server 2008、JTDS JDBC驱动程序1.2.5 (也尝试了1.3.1)

我们环顾了一下网络,在多用户环境中,人们通常会得到这种异常。但是,当我们作为单个用户进行本地测试时,就会发生这种情况。我们尝试了不少建议:

  • 关闭Hibernate乐观锁定(在GORM域实体中禁用版本)
  • 对象在保存到数据库之前锁定对象。

上述任何一项都没有帮助。下面是DataSource.groovy中的一个片段:

代码语言:javascript
复制
    hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    //cache.region.factory_class = 'org.hibernate.cache.SingletonEhCacheRegionFactory' // Hibernate 3
 cache.region.factory_class = 'org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory' // Hibernate 4
    singleSession = true // configure OSIV singleSession mode
    flush.mode = 'manual' // OSIV session flush mode outside of transactional context
}

// environment specific settings
environments {
 local {
  dataSource {
   dbCreate = "update" // one of 'create', 'create-drop','update'
   url = "jdbc:jtds:sqlserver://localhost/test_local"
   username="dbuser"
   password="secret"
   driverClassName="net.sourceforge.jtds.jdbc.Driver"
   logSql = true
   properties {
           maxActive = 100
           maxIdle = 25
           minIdle = 5
           initialSize = 5
           testOnBorrow = true
           validationInterval = 30*1000 //30 seconds
           validationQuery = "SELECT 1"
     //defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
   }
  }
 }
}
EN

回答 1

Stack Overflow用户

发布于 2015-09-11 17:19:58

事实证明,这个StaleObjectStateException问题的来源与配置或代码无关。

我们已经在BootStrap.groovy代码中运行了几个SQL脚本,以便在应用程序启动时初始化数据库(MS )。其中一些SQL脚本包含以下内容

代码语言:javascript
复制
SET NOCOUNT ON;

我们认为,该行会导致Server始终为update语句返回0(可能还会返回其他类型的SQL语句)。当Hibernate执行update语句并检查返回值时,它总是找到0。Hibernate将其与期望值(对于domain.save()调用为1)进行比较。期望值和返回值不匹配,因此Hibernate认为数据陈旧,因此抛出StaleObjectStateException。注意,Hibernate会检查是否打开版本。

希望这个信息能帮助那些有类似情况的人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32386272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档