【问题标题】:Quartz job for Grails cannot update recordGrails 的 Quartz 作业无法更新记录
【发布时间】:2016-07-07 16:04:55
【问题描述】:

我的 Grails 应用程序中有以下 Quartz 作业:

class DataWarehouseJob {

    def execute(context) {

        LeadList list = context.mergedJobDataMap.get('list')

        if (list.processing) {
            return
        }

        list.processing = true
        list.save(failOnError: true)

        ...

    }
}

list 在作业 triggerNow 调用中作为参数传递,并填充了正确的值。此列表已存在于数据库中。但是,当它尝试保存列表时,会出现以下错误:

org.quartz.JobExecutionException: org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session : [haystack.LeadList#169]; nested exception is org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [haystack.LeadList#169]
    at grails.plugins.quartz.GrailsJobFactory$GrailsJob.execute(GrailsJobFactory.java:111)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session : [haystack.LeadList#169]; nested exception is org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [haystack.LeadList#169]

...

Caused by: org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [haystack.LeadList#169]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:618)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:301)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:244)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:109)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90
...

我尝试添加 flush: true 作为参数来保存函数,在保存之前在列表上调用 merge,用 @ExecuteInJTATransaction 注释类,保存 LeadList withNewSession,但没有任何帮助 - 同一行总是发生相同的错误( list.save)

最奇怪的是这段代码以前可以工作,我不确定哪个更改会破坏它 - 在相当长的一段时间内没有提交涉及此类的更改。

代码使用 Grails 3.1.5 编写并在 Tomcat 8 上运行。

【问题讨论】:

    标签: grails quartz-scheduler


    【解决方案1】:

    我不想删除问题,因为解决方案可能会使某人受益。

    问题是因为作业正在接受LeadList 对象,我猜它创建了它的副本而不是通过引用传递对象,这就是导致问题的原因。

    解决方案是将对象的ID作为参数而不是整个对象发送给作业,并且在作业中首先通过ID获取对象,然后再对数据库进行更改:

    // LeadList list = context.mergedJobDataMap.get('list')
    long listId = context.mergedJobDataMap.get('listId')
    LeadList list = LeadList.findById(listId)
    

    不过,我不知道之前传递整个对象是如何工作的,然后在某个时候突然开始导致问题。

    【讨论】:

      猜你喜欢
      • 2016-07-07
      • 1970-01-01
      • 1970-01-01
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多