我在使用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选项完全自动化流程,而不必手动稍后弄乱了架构。
如何使这项工作受到欢迎。
答案 0 :(得分:3)
现在除了使用@DatabaseFiled(version = true)
不适用于Timestamp
字段外,似乎无法实现此目的。这已在主干中得到纠正,并将在4.46中使用:
为了让它与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