【问题标题】:grails joda datetime millis not saved in DB?grails joda datetime millis 未保存在数据库中?
【发布时间】:2015-12-10 05:59:56
【问题描述】:

我尝试根据 validFrom 和 validUntil 属性搜索产品的当前金额,该属性在价格到期时保存信息。

当价格发生变化时,我将旧价格的 validUntil 属性从 null(这意味着有效到无穷大)设置为 Datetime,直到它有效为止。然后我创建一个validUntil 为1 的新价格!!旧的毫秒后有效直到。这样我就可以始终为每种产品提供有效的价格。

这是我的测试用例

def endDateOld = DateTime.parse('2015-09-14T10:49:00+02:00')
log.debug "a "+endDateOld.millis
def startDateNew = new DateTime(endDateOld).plusMillis(1)
log.debug "b "+startDateNew.millis

产生

a 1442220540000
b 1442220540001

当我将它保存到数据库时

def money = new MoneyProduct(validFrom:endDateOld, validUntil:startDateNew, amount:199)
money.save(flush:true)

我得到了我得到的值:

log.debug "from "+money.validFrom.millis+" until "+money.validUntil?.millis

输出:

from 1442220540000 until 1442220540000

MoneyProduct 类:

class MoneyProduct {

    BigDecimal amount 
    Currency currency = Currency.getInstance("EUR")
    DateTime dateCreated

    DateTime validFrom
    DateTime validUntil

    static constraints = {
        validUntil(nullable:true)   
        amount(nullable:false)
    }

    static belongsTo = [product:Product]
}

可能是配置问题? 配置.groovy:

// Added by the Joda-Time plugin:
grails.gorm.default.mapping = {
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentDateMidnight, class: org.joda.time.DateMidnight
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentDateTime, class: org.joda.time.DateTime
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentDateTimeZoneAsString, class: org.joda.time.DateTimeZone
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentDurationAsString, class: org.joda.time.Duration
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentInstantAsMillisLong, class: org.joda.time.Instant
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentInterval, class: org.joda.time.Interval
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentLocalDate, class: org.joda.time.LocalDate
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime, class: org.joda.time.LocalDateTime
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentLocalTime, class: org.joda.time.LocalTime
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentPeriodAsString, class: org.joda.time.Period
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentTimeOfDay, class: org.joda.time.TimeOfDay
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentYearMonthDay, class: org.joda.time.YearMonthDay
    "user-type" type: org.jadira.usertype.dateandtime.joda.PersistentYears, class: org.joda.time.Years
}

编辑:

看起来 joda datetime 数据类型在 mySQL 中存储为 DATETIME,它只有秒精度。我该如何更改?

好的。我需要覆盖默认的休眠映射。我试过了:

static mapping = {
    validFrom sqlType: "DATETIME", length: 3
    validUntil sqlType: "DATETIME", precision: 3
}

默认情况下,grails 似乎正在创建一个没有长度/精度的日期时间列(我使用 joda 插件),默认为 0。这意味着没有精度 = 秒。在我的情况下,我需要毫秒精度,即 @Adam Michalik 建议的 3 的长度/精度(6 为纳米)

当我手动将长度更改为 3 时,grails 更新并完美检索毫秒。

【问题讨论】:

  • 你的数据库是什么?什么是 DB 列类型?
  • 刚刚编辑。 DB 是 mySQL,列自动映射到 DATETIME

标签: grails jodatime


【解决方案1】:

你需要告诉 mysql 你想要的第二个小数的大小 - 范围是 0 到 6。使用

DATETIME(6)

以获得最大的可用精度。默认情况下它是 0,所以你根本不会得到任何毫秒。

引用the documentation

要定义包含小数秒部分的列,请使用语法type_name(fsp),其中type_name 是TIMEDATETIMETIMESTAMPfsp 是小数秒精度。例如:

CREATE TABLE t1 (t TIME(3), dt DATETIME(6));

fsp 值(如果给定)必须在 0 到 6 的范围内。值 0 表示没有小数部分。如果省略,则默认精度为 0。(这与标准 SQL 默认值 6 不同,是为了与以前的 MySQL 版本兼容。)

【讨论】:

  • 好的。但是 grails 正在为我创建表格。如何告诉 grails 以我想要的精度创建列?
  • 我不是 Grails 专家,但这似乎是您覆盖默认生成表设置的方式:grails.github.io/grails-doc/2.2.0/ref/Database%20Mapping/… 请参阅 mapping/type 块以覆盖 SQL 类型
  • 我可以像你描述的那样强制 grails,当它是另一种类型时我会这样做。但由于它是 joda 插件,并且插件正在做自己的映射,我认为这不是解决方案。应该有办法告诉 joda / 或 usertype 使用另一个映射
猜你喜欢
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
相关资源
最近更新 更多