繁体   English   中英

为什么 Hibernate 将 LocalDateTime 映射到时间戳 (MySQL) 以及如何防止它这样做?

[英]Why does Hibernate map LocalDateTime to timestamp (MySQL) and how can I prevent it from doing so?

  1. 我认为众所周知,MySQL 中的timestamp列类型旨在及时存储“时刻”。

  2. 根据LocalDateTime 官方文档,这个类是:

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

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

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

它给我带来了问题,我想在我的数据库中存储原始LocalDateTime值,但是 Hibernate 通过首先将我的所有数据库datetime s 内部转换为“时刻”(特别是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 在从数据库中获取时仍然会进行一些笨拙的转换,因为它认为我正在获取“时刻”而不是“本地日期/时间”值(仍然在内部使用TimestampTypeDescriptor ,它在执行其他任何操作之前转换为Timestamp )。

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

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

因此,为了确保最大的兼容性, java.time.*类型被转换为java.sql.*类型,并且 JDBC 驱动程序只给你java.time.*类型,你必须对它们如何在内部使用做一些假设.

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM