我有一个运行定期作业的Grails应用程序,该应用程序从多个域对象收集信息,然后更新表中的记录以便于跟踪和监视。
此项目使用的是Grails 2.1.1
前两三次工作运行正常,但随后开始失败。抛出的错误是
org.spingframework.dao.DataIntergrityViolationException:
not-null property references a null or transient vale:
Tracker.lastUpdated;
nested exception is org.hibernate.PropteryValueException:
not-null property references a null or tansient value:
Tracker.lastUpdated
所以,在我的域名中我有这个:
package arena
import grails.plugin.multitenant.core.annotation.MultiTenant
@MultiTenant
class Tracker {
static belongsTo = [ plan: Plan ]
boolean active
Integer produced
Integer counted
Integer failed
Integer remaining
Float percentDone
Date lastUpdated
static constraints = {
plan(nullable:false)
produced(nullable:true)
failed(nullable:true)
counted(nullable:true)
remaining(nullable:true)
percentDone(nullable:true)
}
}
在我得到每个计划的作业中,然后更新除lastUpdated之外的所有属性,因为这应该在行更新时自动更新。这导致我的工作失败,因此并非所有的计划跟踪器都会相应地更新。
我是否需要手动设置lastupdated?我不必与其他任何域对象一起使用。
工作每2小时执行一次。该过程的要点是我收集所有租户位置的所有计划。对于每个计划,我计算每个计划的值并更新跟踪记录。
def plans = Plan.createCriteria().list {
projections {
property("id")
}
}
// update or create strawTracker objects
for (plan in plans) {
def collection = Plan.get(plan)
multiTenantService.doWithTenantId(collection.tenantId) {
def tracker = Tracker.findByPlan(collection)
if (!tracker) {
tracker = new Tracker()
tracker.merge(updateTracker(tracker, collection)).save(flush: true)
} else {
if (tracker.active && !collection.status.equals("done")) {
// get info
// println "Update tracker " + collection
def tempTracker = new Tracker()
tempTracker.merge(updateTracker(tracker, collection)).save(flush:true)
}
def updateTracker(Tracker tracker, Plan plan) {
def prodSum = 0
def failSum = 0
def countSum = 0
plan?.Schedules?.each {
// doing calculations here //
}
int tenant = plan.tenantId
tracker.Plan = plan
tracker.active = !plan.status.equals("done")
tracker.produced = prodSum
tracker.strawsFailed = failSum
tracker.countedStraws = countSum
tracker.remaining = plan.quantityOrdered == null? null : (plan.quantityOrdered - countSum)
tracker.percentDone = plan.quantityOrdered == null? null : (countSum * 100 / plan.quantityOrdered)
tracker.tenantId = tenant
return tracker
}
如前所述,它在前几次成功运行,然后当用户更新计划并填写订单时,它开始失败,因此一些跟踪器信息正确更新,但有些不是。