MySQL创建时间戳的ORMLite问题

时间:2012-12-06 13:43:26

标签: mysql timestamp ormlite

我在使用MySql创建时间戳时遇到问题。在DataType.TIME_STAMP定义中未使用特定@DatabaseField条目的情况下,遵循了建议here

我当前的@DatabaseField看起来像这样:

 @DatabaseField(format="yyyy-MM-dd HH:mm:ss", defaultValue="CURRENT_TIMESTAMP")
 private Timestamp updatedAt;

表格上仍然出现错误:

Unable to create table because of [Problems parsing default date
string 'CURRENT_TIMESTAMP' using 'yyyy-MM-dd HH:mm:ss.SSSSSS']

所以它似乎忽略了格式定义,没有格式定义,我仍然得到这个错误:

Unable to create table because of [Problems parsing default date
string 'CURRENT_TIMESTAMP' using 'yyyy-MM-dd HH:mm:ss.SSSSSS']

我已经尝试过指定dataType,将其更改为DATE_TIME等等。我还没有找到一个组合(除了根本不使用Timestamp而只创建一个DATE_TIME,它有效,但不是CURRENT_TIMESTAMP)。

我真的卡住了,因为我过去手动更新了表格,但现在数量正在增长,我希望使用ORMLite中的Create Table选项完全自动化流程,而不必手动稍后弄乱了架构。

如何使这项工作受到欢迎。

1 个答案:

答案 0 :(得分:3)

现在除了使用@DatabaseFiled(version = true)不适用于Timestamp字段外,似乎无法实现此目的。这已在主干中得到纠正,并将在4.46中使用:

  

http://ormlite.com/docs/version-field

为了让它与4.45中的Timestamp字段一起使用是相当的。您需要extends TimeStampType并覆盖以下方法。有关详细信息,请参阅本答案的底部:

@Override
public Object moveToNextValue(Object currentValue) {
    long newVal = System.currentTimeMillis();
    if (currentValue == null) {
        return new java.sql.Timestamp(newVal);
    } else if (newVal == ((java.sql.Timestamp) currentValue).getTime()) {
        return new java.sql.Timestamp(newVal + 1L);
    } else {
        return new java.sql.Timestamp(newVal);
    }
}

然后将您的字段指定为:

@DatabaseField(persisterClass = LocalCurrentTimeStampType.class, version = true)
java.sql.Timestamp timestamp;

[[以下适用于创建日期,但不适用于其他更新。我会留下一般信息。]]

这是非常重要的,但我终于找到了使用trunk中最新版本的方法。在4.46中,我们将为只有只读的字段添加对@DatabaseField(readOnly = true)的支持。这允许你说:

@DatabaseField(defaultValue = "CURRENT_TIMESTAMP()", readOnly = true)
java.sql.Timestamp timestamp;

永远不会创建或更新只读字段 - 仅在查询中返回。问题是TimeStampType在尝试验证CURRENT_TIMESTAMP()时会引发异常。要解决此问题,您需要定义自定义持久性:

public class LocalCurrentTimeStampType extends TimeStampType {
    private static final LocalCurrentTimeStampType singleton =
        new LocalCurrentTimeStampType();
    private String defaultStr;
    public LocalCurrentTimeStampType() {
        super(SqlType.DATE, new Class<?>[] { java.sql.Timestamp.class });
    }
    public static LocalCurrentTimeStampType getSingleton() {
        return singleton;
    }
    @Override
    public boolean isEscapedDefaultValue() {
        if ("CURRENT_TIMESTAMP()".equals(defaultStr)) {
            return false;
        } else {
            return super.isEscapedDefaultValue();
        }
    }
    @Override
    public Object parseDefaultString(FieldType fieldType, String defaultStr) throws SQLException {
        this.defaultStr = defaultStr;
        if ("CURRENT_TIMESTAMP()".equals(defaultStr)) {
            return defaultStr;
        } else {
            return super.parseDefaultString(fieldType, defaultStr);
        }
    }
}

然后您的字段定义变为:

@DatabaseField(persisterClass = LocalCurrentTimeStampType.class,
    defaultValue = "CURRENT_TIMESTAMP()", readOnly = true)
java.sql.Timestamp timestamp;

您可以从github代码获取最新版本:https://github.com/j256/ormlite-core