Java 8 休眠中的 LocalDate 错误地映射到 TIMESTAMP
Java 8 LocalDate in hibernate wrongly mapped to TIMESTAMP
我使用 Spring boot 1.4.2,它带来了 hibernate 5.0.11 (JPA 2.1)。
我想在我的实体中使用 Java 8 次 类,因此包括 hibernate-java8
.
我的实体定义了一个 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)]
令我惊讶的是,如果我将数据库定义更改为 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)]
这只是上一条消息的反向消息。
我也尝试使用 AttributeConverter<LocalDate, java.sql.Date>
而不是包含 hibernate-java8
,但这会产生相同的错误结果。
我必须做什么,才能将我的 LocalDate 正确映射到数据库中的日期?
我还尝试将 LocalDateTime
字段映射到 TIMESTAMP,这没有问题...
我没有在 Spring 中使用它,但在 "standard" 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());
}
}
我的 table 有 "timestamp with timezone" 列。然后我的@Entity 使用 OffsetDateTime。你应该能够用这样的东西在你的数据类型之间进行转换。
所以我通过在 @Column
注释中添加 columnDefinition="DATE"
得到它 运行。
@Entity
@Table(name = "my_alarms_timeline", indexes = {...})
public class MyAlarm {
...
@Column(name = "validity_date", columnDefinition = "DATE")
@NotNull
private LocalDate validityDate;
}
不确定为什么没有其他人看到这个问题...
我怀疑您的项目中某处有以下代码:
@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class })
如果您正在使用 Hibernate 5.x,您应该删除对 Jsr310JpaConverters.class 的引用,否则 Hibernate 和 Spring 都将尝试处理 Java 8 日期和时间对象。这可能会导致一些非常不稳定的行为(例如,当 运行 在不使用 UTC 的机器上时,LocalDate 实例以错误的值持久化)。
您还应该删除任何出现的:
@Column(columnDefinition = "DATE")
如果您需要它,则表明您的休眠配置存在严重错误。
我使用 Spring boot 1.4.2,它带来了 hibernate 5.0.11 (JPA 2.1)。
我想在我的实体中使用 Java 8 次 类,因此包括 hibernate-java8
.
我的实体定义了一个 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)]
令我惊讶的是,如果我将数据库定义更改为 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)]
这只是上一条消息的反向消息。
我也尝试使用 AttributeConverter<LocalDate, java.sql.Date>
而不是包含 hibernate-java8
,但这会产生相同的错误结果。
我必须做什么,才能将我的 LocalDate 正确映射到数据库中的日期?
我还尝试将 LocalDateTime
字段映射到 TIMESTAMP,这没有问题...
我没有在 Spring 中使用它,但在 "standard" 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());
}
}
我的 table 有 "timestamp with timezone" 列。然后我的@Entity 使用 OffsetDateTime。你应该能够用这样的东西在你的数据类型之间进行转换。
所以我通过在 @Column
注释中添加 columnDefinition="DATE"
得到它 运行。
@Entity
@Table(name = "my_alarms_timeline", indexes = {...})
public class MyAlarm {
...
@Column(name = "validity_date", columnDefinition = "DATE")
@NotNull
private LocalDate validityDate;
}
不确定为什么没有其他人看到这个问题...
我怀疑您的项目中某处有以下代码:
@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class })
如果您正在使用 Hibernate 5.x,您应该删除对 Jsr310JpaConverters.class 的引用,否则 Hibernate 和 Spring 都将尝试处理 Java 8 日期和时间对象。这可能会导致一些非常不稳定的行为(例如,当 运行 在不使用 UTC 的机器上时,LocalDate 实例以错误的值持久化)。
您还应该删除任何出现的:
@Column(columnDefinition = "DATE")
如果您需要它,则表明您的休眠配置存在严重错误。