【问题标题】:dateCreated, lastUpdated fields in Grails 2.0Grails 2.0 中的 dateCreated、lastUpdated 字段
【发布时间】:2012-02-21 13:31:37
【问题描述】:

我有一个使用 Grails 1.3.7 的应用程序,我刚刚迁移到 Grails 2.0。该应用程序使用自动dateCreatedlastUpdated 字段来管理与对象的创建和修改相关的时间戳。升级后出现如下错误:

| Running Grails application
| Error 2012-01-29 22:36:53,504 [Thread-8] ERROR util.JDBCExceptionReporter  - ERROR: null value in column "date_created" violates not-null constraint
| Error 2012-01-29 22:36:53,510 [Thread-8] ERROR events.PatchedDefaultFlushEventListener  - Could not synchronize database state with session

在我的域类中注释掉上述字段会使问题消失。

dateCreatedlastUpdated 字段在 Grails 2.0 中是否已被弃用?如果是这样,这是否意味着我必须编写代码来手动处理此功能,或者代码是否已移至某种插件,例如 audit-trail 插件?

【问题讨论】:

    标签: grails grails-orm grails-domain-class grails-2.0


    【解决方案1】:

    好的,通过在域类定义中手动将 autoTimestamp 变量设置为“true”来修复它:

    static mapping = {
            autoTimestamp true
    }
    

    我猜这个属性在将项目从 Grails 1.3.7 迁移到 2.0.0 后没有设置。

    【讨论】:

    • 非常感谢!我遇到了一个问题,因为 grails 2.2.0 覆盖了我在域类中设置的值。而更危险的是Grails添加的timeStamp是依赖于系统时钟的。
    • 我通过将 autoTimestamp 属性设置为 false 修复了自动覆盖
    【解决方案2】:

    Grails 2.0 仍然支持自动时间戳。 It's listed in the manual (scroll up a bit from this link).

    但是,它特别提到:

    如果您对dateCreatedlastUpdated 施加nullable: false 约束,您的域实例将无法通过验证——可能不是您想要的。除非您禁用了自动时间戳,否则请不要限制这些属性。

    【讨论】:

    • 您发布的链接转到localhost/~phil。你放错链接了吗?
    • 约束中根本没有提到这两个字段。根据引用的文字,我开始认为我可能以某种方式禁用了“自动时间戳”。你从哪里得到的文本?
    • 抱歉,我正在浏览我的离线副本。链接已修复。警告消息在我链接的页面上。您必须从链接中滚动 UP,因为我无法直接链接。
    • 好的,通过在域类定义中手动将 autoTimestamp 变量设置为“true”来修复它。我猜这个属性在将项目从 Grails 1.3.7 迁移到 2.0.0 后没有设置。
    • 我相信 Grails 2.X 仍然有 autoTimestamp 作为默认行为,正如 OverZealous 所说,但我想知道是否有特定的插件覆盖它。我有一些项目可以很好地解决这个问题,但我刚刚看到我们工作中的应用程序开始表现出这种行为。
    【解决方案3】:

    Grails 2.0.3 中有一个错误,在使用 Postgres 时可能会导致此问题。见http://jira.grails.org/browse/GRAILS-8988。这个问题说它会在 2.0.4 发布时解决。

    【讨论】:

      【解决方案4】:

      如果您使用 Grails 4,我找到了一个替代解决方案:

      class ScheduledTaskServiceSpec extends Specification implements ServiceUnitTest<ScheduledTaskService>{
      
          @Shared @AutoCleanup HibernateDatastore hibernateDatastore
          @Shared AutoTimestampEventListener timestamper
      
          void setupSpec() {
              hibernateDatastore = new HibernateDatastore(RegistrationCode)
              timestamper = hibernateDatastore.getAutoTimestampEventListener()
          }
      
          @Transactional
          @Rollback        
          void 'some test method'() {
              when:
              timestamper.withoutDateCreated(MyDomainClass) {
                  MyDomainClass mdc = new MyDomainClass(name:"foo")
                  mdc.dateCreated = new Date() - 20
              }
      
              then:
              MyDomainClass.findByName("foo").dateCreated < new Date()
          }
      }
      

      参考

      AutoTimestampEventListener

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2012-11-11
        • 2012-06-28
        • 1970-01-01
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        • 1970-01-01
        • 2011-08-09
        相关资源
        最近更新 更多