2017-05-20 71 views
1

我有一個使用帶有datetimeoffset列的SQLServer數據庫的應用程序。最好,我想用ZonedDateTime作爲我JPA實體對象的類型,像這樣:在SQLServer中使用帶有datetimeoffset的ZonedDateTime

@Column(name = "CreateTimestamp", nullable = false) 
ZonedDateTime createTimestamp; 

然而,時區沒有被正確保存。無論我在ZonedDateTime中將ZoneId設置爲什麼,該值在數據庫中始終以GMT格式。

看着Microsoft's JDBC mapping diagram,推薦使用的類是microsoft.sql.DateTimeOffset,這不是我所希望的。

我已經探索過使用@Converter來映射這兩者之間的關係,但必須提供像這樣的特殊知識,看起來像一個紅旗,我做錯了什麼事情 - 特別是因爲我需要這個工作在一個集成使用H2進行測試。

以供應商不可知的方式使用datetimeoffset和ZonedDateTime的最佳方式是什麼?

回答

1

我討厭回答我自己的問題,但我想確保解決方案被記錄在案。

解決方案是使用@Converter將ZonedDateTime轉換爲字符串。 Hibernate會將其作爲VARCHAR傳遞給SQLServer,並且數據庫本身將隱式地將該值轉換爲datetimeoffset - 與執行獨立查詢時轉換硬編碼日期的方式相同。

下轉換器工作了我的情況:

@Converter(autoApply = true) 
public class ZonedDateTimeConverter implements AttributeConverter<ZonedDateTime, String> 
{ 
    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSSS xxx"; 

    @Override 
    public String convertToDatabaseColumn(ZonedDateTime zonedDateTime) 
    { 
     return DateTimeFormatter.ofPattern(DATE_FORMAT).format(zonedDateTime); 
    } 

    @Override 
    public ZonedDateTime convertToEntityAttribute(String dateAsString) 
    { 
     return ZonedDateTime.parse(dateAsString, DateTimeFormatter.ofPattern(DATE_FORMAT)); 
    } 
} 

此外,這也適用於H2,因此它可以集成測試的內部使用,而無需做任何特定供應商的邏輯。