【问题标题】:Spring Data JPA with Java 8 LocalDateTime使用 Java 8 LocalDateTime 的 Spring Data JPA
【发布时间】:2018-02-12 15:48:42
【问题描述】:

过去几个月我一直在使用 Spring Data JPA 和 MYSQL,这是一次非常成功和顺利的体验。在那里,我使用 java 8 LocalDateTime 来存储日期时间字段,JPA 自动将这些字段映射到 mysql tinyblob 列。

最近我需要通过脚本向系统添加一些数据。为了填充日期时间列,我创建了 MYSQL TIMESTAMP 变量并插入到 tinyblob 列中。然而,系统开始抱怨 SerializationException 并且根本原因是这个转换的日期时间列。 然后我查看了通过应用程序插入的日期时间列,如下所示

select CAST(drop_off_time AS CHAR(10000) CHARACTER SET utf8) From job

看起来,当您通过应用程序插入时,它作为某种 java 序列化插入。但是通过 mysql 脚本,我们无法复制该功能。

现在我有两个选择。 1)我需要找到一种方法来编写一个mysql脚本来生成类似于应用程序的日期时间列。 2) 我需要将 Spring 数据 JPA 映射从 tinyblob 更改为 mysql 脚本可以支持的另一种数据类型

感谢您的帮助

谢谢, 凯斯

编辑

按照下面提供的答案和cmets,我找到了一个简单的解决方案

如果你使用 Hibernate 5.0+,你可以加入

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>${hibernate.version}</version>
</dependency>

然后系统开始将 java 8 LocalDateTime 属性映射到 mysql DATETIME 列

【问题讨论】:

  • 不支持 Java 8 日期时间 API 取决于哪个 Hibernate 版本,它将被存储为二进制而不是时间戳。
  • LocalDateTime 不应存储在 blob 中。这使得无法查询日期,无法在 Java 以外的任何地方使用该值,并且占用的磁盘空间比必要的多得多。最新版本的 Hibernate 开箱即用地支持 LocalDateTime,存储为日期/时间戳(请参阅docs.jboss.org/hibernate/orm/5.2/userguide/html_single/…)。您使用的是哪个版本的 spring/hibernate?
  • 检查这个 depyendency,它将添加 java8 datetime api 支持到休眠:search.maven.org/… 据我所知,它仅适用于 Hibernate 5
  • 我希望 LocalDateTime 一开始就会映射到 TIMESTAMP(没有 TZ)。我不相信 db 脚本形式的任何东西可以“修复”您的数据 - 但是,您可以在 hava 中迭代整个数据集并将反序列化的数据正确地写回时间戳列。除此之外,请参阅this question
  • 然后,正如该版本的文档所述(请参阅docs.jboss.org/hibernate/orm/5.0/userguide/html_single/…),您应该将 hibernate-java8 jar 文件添加到您的依赖项中。或者您可以升级到最新版本。

标签: mysql jpa java-8 spring-data spring-data-jpa


【解决方案1】:

根据 JPA 2.1 LocalDateTime 不被官方支持(可能在短时间内 JPA 2.,2 将是官方的)。 Hibernate 5 支持“早期版本”

由于 JPA 2.0 是 javax.persistence.AttributeConverter,因此可移植和受支持,在所有 JPA 提供程序上都运行良好(并且在 Hibernate 5 上没有任何问题)

@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {

@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
    return (locDate == null ? null : Date.valueOf(locDate));
}

@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
    return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}

【讨论】:

    猜你喜欢
    • 2015-05-31
    • 2015-02-28
    • 2015-07-30
    • 2020-07-21
    • 1970-01-01
    • 2017-03-08
    • 2017-03-16
    • 1970-01-01
    • 2015-03-01
    相关资源
    最近更新 更多