MySQL DATETIME精度(joda-time,Hibernate,org.jadira.usertype,hbm2ddl)

Pav*_* S. 5 java mysql hibernate jodatime hbm2ddl

在我的hibernate-4实体中,我使用推荐的jadira usertypes映射joda-time DateTime属性:

@Entity
@Table(name="timing")
public class TimingEntity {
    ...
    @Basic(optional=false)
    @Column(name="moment")
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
    public DateTime getMoment() {
       ...
Run Code Online (Sandbox Code Playgroud)

我的数据库是MySQL.将hibernate属性hbm2ddl.auto设置为createvalue,我在timing表中生成了以下列:

CREATE TABLE `timing` (
    ...
   `moment` DATETIME NOT NULL,
    ...
)
Run Code Online (Sandbox Code Playgroud)

生成的CREATE TABLE包含DATETIME列.MySQL中的DATETIME只有秒精度,没有小数部分.为了启用小数部分,高达微秒,MySQL 5.6.4及更高版本启用 DATETIME(precision)列,例如DATETIME(3)具有毫秒精度.

我的问题是 - 有没有办法为hbm2ddl生成的时间字段指定精度?至少,这是jadira usertypes,或java.sql,或jdbc驱动程序机制的问题?

PS当我手动修改数据库表以获得我想要的精确列精度时DATETIME(3),一切正常 - joda DateTimes以毫秒精度从DB写入和读取.

Pav*_* S. 6

我找到了另一个解决方案,允许不在您的@Column注释中硬编码MySQL列定义片段.通过覆盖来定义自己的hibernate方言org.hibernate.dialect.MySQLDialect:

package org.yourproject;

import java.sql.Types;
import org.hibernate.dialect.MySQL5Dialect;

public class MySQL564PlusDialect extends MySQL5Dialect {
   public MySQL564PlusDialect() {
      super();
      registerColumnType( Types.TIMESTAMP, 6, "datetime($l)" );
   }
}
Run Code Online (Sandbox Code Playgroud)

并将其指定为hibernate属性hibernate.dialect=org.yourproject.MySQL564PlusDialect(您想要扩展的方言可能会有所不同,例如org.hibernate.dialect.MySQL5InnoDBDialect相反).

现在,您可以调整的精度DATETIME从内@Column使用注解length属性:

@Basic(optional=false)
@Column(name="moment", length=3)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment() {
 ...
Run Code Online (Sandbox Code Playgroud)

这将产生DATETIME(3)列定义意味着毫秒精度.如果您需要简单DATETIME(无小数秒),则不要指定长度.您可以使用length最多6的值,这意味着微秒的精度.

如果您碰巧使用与上述方言不同的方言(例如标准语言org.hibernate.dialect.MySQLDialect或其他数据库),则不会破坏您的代码:length属性on @Column将被忽略.

PS利用替代precision属性更为明智,但在我自己的方言实现中用一个简单替换模式不能随意工作.@Columnlength"datetime($l)""datetime($p)"


Ily*_*lya 3

使用可以使用@Column#columnDefinition属性

@Basic(optional=false)
@Column(name="moment" columnDefinition="DATETIME(3) NOT NULL")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
public DateTime getMoment() 
{   
   ...
Run Code Online (Sandbox Code Playgroud)

您也可以尝试@Column# precision属性,但在文档中写道,这仅适用于小数。