2016-11-09 48 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配置。