2012-12-06 76 views
3

我在使用MySql創建時間戳時遇到問題。根據here的建議,未使用@DatabaseField定義中的特定DataType.TIME_STAMP條目。MySQL創建時間戳的ORMLite問題

我現在@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,c掛到DATE_TIME等。我還沒有找到一個組合(除了不使用時間戳,只是創建一個DATE_TIME,它的工作原理,但不是與CURRENT_TIMESTAMP)。

我真的陷入困境,因爲我過去手動更新了表,但現在數量在不斷增加,我希望使用ORMLite中的創建表選項完全自動化,而不必稍後手動混淆架構。

任何指針將非常歡迎如何得到這個工作。

+0

有可能是一個消息安東尼問題在這裏問題是''CURRENT_TIMESTAMP''不能用作默認值,因爲它與轉換模式不匹配。不知怎的,我想我需要特殊情況。由於每種數據庫類型都有不同的表現,這將是一個痛苦。 – Gray

+0

哇!感謝Grey的超快反應。我理解這個問題,對待它的一種方式是讓用戶弄清楚它?如果你把MySQL版本放到Postres中,表格創建自然會失敗。所以如果你看到我的意思,那麼這是一個類設計問題,而不是基礎設施問題。也許只是簡單地接受在DefaultValue字段中輸入的任何內容,僅適用於時間戳?用戶有責任讓它正確。那對你有用嗎? – Anthony

+0

是的,這可能是正確的解決方案。 _perfect_解決方案應該在抽象數據庫類型上有某種Timestamp驗證器。 :-)我其實有點驚訝,它需要做字符串解析。我今天晚些時候會看。 – Gray

回答

3

現在看來除了使用不適用於Timestamp字段的@DatabaseFiled(version = true)之外,看起來並不是一種方法。這已得到糾正在樹幹和將在4.46合作:

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

爲了得到它與時間戳字段在4.45的工作是非常每個雖然。您需要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; 

[用於創建日期,但不爲其他更新以下工作。我會留下它的一般信息。]]

這是非平凡的,但我終於想出了你可以做到這一點,使用最新版本的幹線。在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

+0

謝謝格雷 - 我理解技術限制,但至少可以節省編輯大量的表。 – Anthony

+0

我在自訂表格上使用ORMlite時遇到了奇怪的行爲。如果我使用'cdate TIMESTAMP DEFAULT CURRENT_TIMESTAMP'列創建一個表,並且不在對象定義中將其標記爲'@DatabaseField(readOnly = true)',即使直接創建表,它也不會設置默認時間戳。執行插入語句時,ORMlite是否顯式設置空值? – Phidelux