0

tl:博士;这有点涉及问题,欢迎任何建议,感谢提前阅读:)

我和我的同事一直在为我们的批处理应用程序中的奇怪行为而苦苦挣扎。我们最近将它从 Grails 1.3.7 升级到 2.1

堆栈跟踪显示以下错误:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 
  Cannot insert the value NULL into column 'date_created', 
  table 'dev.dbo.notification_log'; column does not allow nulls. INSERT fails.
  ...
[quartzScheduler_Worker-1] [||] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null id in com.virtuwell.domain.NotificationLog entry (don't flush the Session after an exception occurs)
    at org.quartz.core.QuartzScheduler.notifyJobListenersWasExecuted(QuartzScheduler.java:1891)
    at org.quartz.core.JobRunShell.notifyJobListenersComplete(JobRunShell.java:352)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)

[quartzScheduler_Worker-1] [||] ERROR listeners.SessionBinderJobListener  - Cannot flush Hibernate Sesssion, error will be ignored
org.hibernate.AssertionFailure: null id in com.virtuwell.domain.NotificationLog entry (don't flush the Session after an exception occurs)
    at org.quartz.core.QuartzScheduler.notifyJobListenersWasExecuted(QuartzScheduler.java:1891)
    at org.quartz.core.JobRunShell.notifyJobListenersComplete(JobRunShell.java:352)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:223)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)

这是该特定域对象(NotificationLog)的代码

class NotificationLog implements Serializable{
    Date dateCreated
    Notification notification
    NotificationDeliveryState deliveryState
    String message

    static mapping = {
       message type: 'text'
    }
}

然而,奇怪的是,每次持久化域对象时都不会发生此错误,并且我们在代码中只有一个位置会持久化对象,如下所示:

class NotificationLogService {

    boolean transactional = true

    def logNotification(Notification notification, message, deliveryState) {

        def notificationLog = new NotificationLog(
                notification: notification,
                deliveryState: deliveryState,
                message:message
        )

        try{
            notificationLog.save(failOnError:true)
        } catch (Exception e) { // Failure to save a notificationLog should not rollback the calling transaction
            log.error "NotificationLog State:[$deliveryState] for notification:${notification?.id} did not save. Errors: ${notificationLog?.errors}, Message:$message", e
        }


    }
}

我们在下面的 SO 问题中发现了一种解决方法的“hack”,通过将其添加到域对象中,我们不再定期在日志中看到错误

static mapping = {
    autoTimestamp true
}

但这不是我们看到的唯一一个域,SAME 定期保存失败(因此,我需要将映射添加到其他域),如果这确实是dateCreated在 Grails 2.1 中正常运行所必需的,我需要将其添加到更多域!

更糟糕的是,我无法在单元或集成测试中重现它,它只发生在我们正在运行的开发和 QA 实例上。

所以,2个问题:

  1. 有谁知道为什么这个错误可能会定期发生?

  2. 如果没有,有没有办法可以将此映射全局autoTimestamp true添加到我项目的所有域对象(除了将其设置为之外,我根本找不到有关如何添加它的文档false

相关的 SO 问题: Grails 2.0 中的 dateCreated、lastUpdated 字段

相关 Grails 邮件列表讨论 http://grails.1312388.n4.nabble.com/dateCreated-lastUpdated-in-Grails-2-0-td4337894.html

关于 autoTimestamp GORM 属性的相关 Grails 文档 http://grails.org/doc/latest/guide/GORM.html#eventsAutoTimestamping

4

2 回答 2

3

要回答这两个问题:

  1. 编辑尝试flush: truesave否则autoTimestamp true是最后的手段。我没有研究找出这个问题的原因。

  2. 您可以设置此属性Config.groovy以使其适用于所有domain类。

    grails.gorm.default.mapping = {
        autoTimestamp true //or false based on your need
    }
    
于 2013-04-24T22:55:33.017 回答
0

您是否尝试在创建新的 NotificationLog 时手动插入日期?像这样:

class NotificationLogService {

boolean transactional = true

def logNotification(Notification notification, message, deliveryState) {

    def notificationLog = new NotificationLog(
            dateCreated: new Date(),
            notification: notification,
            deliveryState: deliveryState,
            message:message
    )

    try{
        notificationLog.save(failOnError:true)
    } catch (Exception e) { // Failure to save a notificationLog should not rollback the calling transaction
        log.error "NotificationLog State:[$deliveryState] for notification:${notification?.id} did not save. Errors: ${notificationLog?.errors}, Message:$message", e
    }


}

}

于 2013-04-24T21:59:42.790 回答