2016-11-09 49 views
4

我使用Spring boot 1.4.2,它帶來了hibernate 5.0.11(JPA 2.1)。 我想在我的實體中使用Java 8時間類,因此包含hibernate-java8Java 8 Localization在hibernate中錯誤地映射到TIMESTAMP

我的實體定義了一個LocalDate字段。

@Entity 
@Table(name = "my_alarms_timeline", indexes = {...}) 
public class MyAlarm { 
    ... 
    @Column(name = "validity_date") 
    @NotNull 
    private LocalDate validityDate; 
} 

我希望這將映射到我的H2數據庫中的日期。

在我的數據庫中,我聲明這是validity_date DATE NOT NULL,

當我嘗試運行測試,我得到以下錯誤: [INFO] Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [validity_date] in table [my_alarms_timeline]; found [date (Types#DATE)], but expecting [timestamp (Types#TIMESTAMP)]

令我驚訝的是,如果我改變了DB定義validity_date TIMESTAMP NOT NULL,我得到的錯誤

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [validity_date] in table [my_alarms_timeline]; found [timestamp (Types#TIMESTAMP)], but expecting [date (Types#DATE)]

這是隻是前一個的反向信息。

我也試過,而不是包括hibernate-java8,使用AttributeConverter<LocalDate, java.sql.Date>,但這會產生相同的錯誤結果。

我必須做什麼,以便我的LocalDate正確映射到DB中的DATE?

我也試圖與映射到TIMESTAMP爲LocalDateTime場,而這個工程沒有問題...

回答

5

所以我通過在@Column註釋中添加columnDefinition="DATE"來運行它。

@Entity 
@Table(name = "my_alarms_timeline", indexes = {...}) 
public class MyAlarm { 
    ... 
    @Column(name = "validity_date", columnDefinition = "DATE") 
    @NotNull 
    private LocalDate validityDate; 
} 

不知道爲什麼沒有其他人看到這個問題...

+1

這對我有用。我使用的是使用Hibernate 5.0.12的Spring Boot 1.5.4。奇怪的是,我的Entity對象中的一個ZonedDateTime列被映射到MySQL VARBINARY ...但好消息是,這個問題已經修復了! – jtcotton63

+0

得到了這個'[Request processing failed;嵌套異常是org.springframework.orm.jpa.JpaSystemException:無法反序列化;嵌套異常是org.hibernate.type.SerializationException:無法反序列化]與根源 java.io.StreamCorruptedException:無效流報頭:32303138 \t在java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:863) \t在java.io.ObjectInputStream中。 (ObjectInputStream.java:355) \t at org.hibernate.internal.util.SerializationHelper $ CustomObjectInputStream。 (SerializationHelper.java:309)' –

1

我沒有在春天,但在「標準」 JPA用這個,我做了類似的東西:

@Converter(autoApply = true) 
public class OffsetDateTimeAttributeConverter implements AttributeConverter<OffsetDateTime, Timestamp> { 
    @Override 
    public Timestamp convertToDatabaseColumn(OffsetDateTime entityValue) { 
     if(entityValue == null) 
      return null; 

     return Timestamp.from(Instant.from(entityValue)); 
    } 

    @Override 
    public OffsetDateTime convertToEntityAttribute(Timestamp databaseValue) { 
     if(databaseValue == null) 
      return null; 

     return OffsetDateTime.parse(databaseValue.toInstant().toString()); 
    } 
} 

我的表具有「timezone with timezone」列。然後,我的@Entity使用OffsetDateTime。你應該可以在你的數據類型之間進行類似的轉換。

+0

我也嘗試過使用AttributeConverter ,但是失敗的時候會出現同樣的錯誤。我想這就是hibernate-java8包的方法。 – Philipp

1

我懷疑你在你的項目中有下面的代碼的地方:

@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class }) 

如果您正在使用Hibernate 5。 x您應該刪除對Jsr310JpaConverters.class的引用,否則Hibernate和Spring將嘗試處理Java 8 Date和Time對象。這可能會導致一些非常不穩定的行爲(例如,在不使用UTC的計算機上運行時,LocalDate實例會被保存爲錯誤的值)。

你也應該刪除任何出現:

@Column(columnDefinition = "DATE") 

如果你需要它,這是一個跡象表明,事情是嚴重的錯誤Hibernate配置。