首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有动态查找器的Grails StaleObjectException (Hibernate)

带有动态查找器的Grails StaleObjectException (Hibernate)
EN

Stack Overflow用户
提问于 2014-06-03 06:07:18
回答 1查看 225关注 0票数 1

我有一个批处理作业,它总是在动态查找器上抛出陈旧的对象异常。理想情况下,我不会为这项工作运行ORM解决方案,但我别无选择。异常发生在从FormulaBatchPopulatorService调用的FormulaTagService中。此应用程序正在使用一个数据库的两台服务器上运行。一台服务器只是执行批处理。

我的问题是: a)为什么一个简单的select语句,导致一个域对象实例,在给定的事务期间没有对对象进行任何更改,最终会在会话中持久化,从而导致陈旧的对象异常?b)是否有可能在事务结束时持久化在formula.tags上进行的排序,从而在其他人修改不同服务器上的公式时导致staleobjectexception?

请注意,我确实将服务更改为只读,但我仍然得到过时的对象异常。任何帮助都将不胜感激。

公式标记服务

代码语言:javascript
运行
复制
@Cacheable("formulaJob")
      def getFormulaByTeacherTagsOrDefaultBatchJob(Long evaluationTemplateId, List teacherTags) {
          Long formulaByTagsId = existsFormulaWithSameTagsBatchJob(evaluationTemplateId, teacherTags)

          if (DefaultFormulaForEvaluationTemplate.get(evaluationTemplateId) == null && formulaByTagsId ==    
             null) {
               return null;
          }

        Long defaultFormulaId = DefaultFormulaForEvaluationTemplate.get(evaluationTemplateId).formulaId
        return formulaByTagsId ?: defaultFormulaId
    }

    def existsFormulaWithSameTagsBatchJob(Long evaluationTemplateId, List tags){
       // LINE BELOW THROWING STALE OBJECT EXCEPTIONS
        def formulas = Formula.findAllByExtEvaluationTemplateIdAndIsActive(evaluationTemplateId, true)

        for (Formula formula: formulas) {
            def formulaTags = formula.tags
            if (existsTagMatchIgnoringBlankTags(tags, formulaTags)) {
                def id = formula.id
                formula.discard()
                return id
            }
        }
    }

    @CacheEvict(value='formulaJob', allEntries=true)
    def resetTags(){
    }

    def existsTagMatchIgnoringBlankTags(List tagsToCompare, List tagsExisting) {
          if (!tagsToCompare || !tagsExisting) {
              return false
           } 
           else {
               return tagsToCompare?.sort() == tagsExisting?.sort()
            }
    }

FormulaBatchPopulatorService代码段

代码语言:javascript
运行
复制
   //Doing this below to improve performance of batch processing
         if(index%250==0){
             cleanUpGorm()
             formulaTagService.resetTags()  //cache-evict in formulatagservice
         }
    
         def cleanUpGorm(){
            def session = sessionFactory.currentSession
            session.flush()
            session.clear()
            propertyInstanceMap.get().clear()
        }
EN

回答 1

Stack Overflow用户

发布于 2014-08-31 04:59:27

我相信你的答案是正确的:

b)是否有可能在事务结束时持久化在formula.tags上进行的排序,从而在其他人修改不同服务器上的公式时导致staleobjectexception?

如果您对标签进行排序,并且它是一个列表,我相信Groovy会在适当的位置执行此操作,即对原始列表进行排序并返回它。然后,该列表将在以下时间之一被持久保存:

transaction

  • end of
  1. 下次在当前会话中执行数据库查询时结束(例如,findBy将刷新会话)

它是持久化的,因为索引字段可能已经改变,所以被GORM / hibernate认为是脏的。

我有一个类似的问题,导致了同样的问题。我在验证它的时候遇到了这一点,看看其他人是否也面对它。

不确定只读部分是怎么回事!你的服务是事务性的吗?

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

https://stackoverflow.com/questions/24004083

复制
相关文章

相似问题

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