【问题标题】:Why does Hibernate map LocalDateTime to timestamp (MySQL) and how can I prevent it from doing so?为什么 Hibernate 将 LocalDateTime 映射到时间戳(MySQL),我该如何防止它这样做?
【发布时间】:2021-07-07 22:49:56
【问题描述】:
  1. 我认为众所周知,MySQL 中的timestamp 列类型旨在及时存储“时刻”。

  2. 根据LocalDateTime official docs,这个类是:

在 ISO-8601 日历系统中没有时区的日期时间,例如 如 2007-12-03T10:15:30。 LocalDateTime 是一个不可变的日期时间对象 表示日期时间,通常被视为 年月日时分秒

并且通常用于存储带时间的日期,而不是“时刻”(它不像Instant等其他“时刻”数据类型那样使用UTC作为参考存储)。

那么为什么 Hibernate 将 LocalDateTime 字段映射到数据库中的 timestamp 字段呢?据我了解,它们用于不同的事物!

这给我带来了问题,我想在我的数据库中存储原始 LocalDateTime 值,但是 Hibernate 通过在内部首先将我的所有数据库 datetimes 转换为“moments”(特别是 java.sql.Timestamp)破坏了这一点

这是一个错误吗?设计缺陷?还是我错了?

顺便说一句,我已经尝试过像这样设置我的实体

public class MyEntity implements Serializable {

    @Id
    private Long id;

    @Column(name = "my_date_time_field", columnDefinition = "DATETIME")
    private LocalDateTime myDateTimeField = LocalDateTime.now();

并且 Hibernate 在从数据库中获取时仍然会进行一些 awkard 转换,因为它认为我正在获取“时刻”而不是“本地日期/时间”值(内部仍然使用 TimestampTypeDescriptor,它转换为 @987654332 @ 在做任何其他事情之前)。

PD:我知道以 UTC 格式处理所有日期/时间是标准做法。由于客户的要求,我不能这样做。他们只想查看数据库中的本地日期和时间,并且永远不会看到它们被转换,即使它们位于不同的时区。他们明确告诉我他们不关心“时刻”的概念,因为他们的业务并没有像那样根本运作(经过数周的解释和争论,我很确定他们知道会带来什么后果)。

【问题讨论】:

  • 根据documentationtimestamp类型是:“TIMESTAMP数据类型用于同时包含日期和时间部分的值。TIMESTAMP的范围是'1970-01-01 00 :00:01' UTC 到 '2038-01-19 03:14:07' UTC。"。你的意思是time 类型吗?
  • 这会导致什么具体问题?即“我存储 X,然后我返回 Y 而不是 Z”(给定特定的客户端和服务器时区)
  • 在我使用 Hibernate(以及 EJB)的地方,我们总是明确定义数据库表,而不是让它们自动创建。
  • 我认为 Hibernate 没有理由这样做。您使用的是哪个版本以及哪种方言?

标签: java mysql spring hibernate java-time


【解决方案1】:

这样做是因为 JDBC 驱动程序只能期望支持 java.sql.Datejava.sql.Timejava.sql.Timestamp 类型,并且没有标准机制来检查驱动程序支持哪些类型以使用 setObject 作为参数.即使 MySQL 驱动程序支持它,也无法知道是否有任何过时的中间件抽象层不会尝试验证该参数并拒绝它。

因此,为了确保最大的兼容性,java.time.* 类型被转换为java.sql.* 类型,而 JDBC 驱动程序只为您提供java.time.* 类型,您必须对它们的内部使用方式做出一些假设。

这不是 Hibernate 的设计缺陷,而是他们处理可用标准中未定义行为的方法。即使在 JDBC 标准中引入了解决这个问题的机制,仍然需要数年时间才能在所有级别上传播到足够多的支持以供他们使用。

【讨论】:

  • 很好的答案,这完全有道理。你知道有什么干净的方法让它表现得像我想要的那样吗?
  • 您可以在配置中设置一些属性来设置 Hibernate 的时区,但我不知道这是否正是您想要的。如果这不起作用,那么所有的方式都是肮脏的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 2023-03-29
  • 2017-05-17
  • 2016-02-25
  • 2015-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多