在 Hibernate 中持久化 Joda DateTime 而不是 Java Date

Posted

技术标签:

【中文标题】在 Hibernate 中持久化 Joda DateTime 而不是 Java Date【英文标题】:Persisting Joda DateTime instead of Java Date in Hibernate 【发布时间】:2011-01-12 10:46:00 【问题描述】:

我的实体当前包含 java Date 属性。我开始经常使用 Joda Time 进行日期操作和计算。这意味着我必须不断地将我的 Dates 转换为 Joda DateTime 对象,然后再转换回来。

所以我想知道,有什么理由不应该只更改我的实体来存储 Joda DateTime 对象而不是 Java Date 对象?

请注意,这些实体是通过 Hibernate 持久化的。我找到了jodatime-hibernate 项目,但我也在 Joda 邮件列表上看到它与较新版本的 hibernate 不兼容。而且好像维护得不太好。

所以我想知道是否最好继续在 Date 和 DateTime 之间进行转换,或者开始持久化 DateTime 对象是否明智。我担心的是依赖于维护不善的库。

编辑:请注意,我的目标之一是能够更好地存储时区信息。仅存储日期似乎可以将日期保存在本地时区。由于我的应用程序可以在全球范围内使用,因此我还需要知道时区。 Joda Time Hibernate 似乎也在 the user guide 中解决了这个问题。

【问题讨论】:

目前,Hibernate 的用户类型似乎是比 joda-time hibernate 更流行和受支持的解决方案。有关更多信息,请参阅下面@Chris 的答案。 +1,我想知道完全相同的事情。 【参考方案1】:

Joda Time Hibernate 可以与最近的 Hibernate 版本一起使用 - 您可能需要稍微调整一下依赖关系图,仅此而已(例如设置排除项)。我还可以建议您查看我已在 Sourceforge 上发布的用户类型。这提供了 Joda Time 的用户类型,旨在避免您提到的客户端偏移问题。我欢迎您对该项目的任何反馈。 https://sourceforge.net/projects/usertype/files/

问候克里斯。

【讨论】:

【参考方案2】:

我认为使用 Joda DateTime 作为您的 bean 属性类型可能是一个好主意。然后,您可以让 Hibernate 进行转换并将属性保存为本地数据库日期格式。

我个人使用过 jodatime-hibernate,没有遇到任何问题(我们使用的是 Hibernate 3.2.5GA)。

如果您对 jodatime-hibernate 有疑虑,您可以随时使用 Hibernate's custom type mapping mechanism(我敢肯定 jodatime-hibernate 就是这样做的)。

【讨论】:

我很高兴听到您成功地将 joda-time 用于 bean 属性。我正在使用 Hibernate 3.3,这听起来像是人们遇到了麻烦。但我相信你是对的,joda-time 只是一个休眠的自定义类型,所以也许通过一些调整我可以让它工作。【参考方案3】:

所以,总结一下:

java.util.Date

+ Hibernate 中的原生支持 – 错误的 API

乔达时间

+ 更好的 API – Hibernate 缺乏原生支持

就个人而言,如果我可以通过使用第三方库(在这种情况下显然是User Type for Hibernate)来保持域模型和“服务层”的清洁,那么另一种选择是编写一些额外的代码来“手动”进行转换" 每次需要的时候,我都会去第三方库。

【讨论】:

【参考方案4】:

不应使用高级抽象来存储日期,例如字符串 ("2009-08-07 07:43:19 ...") 或 Java 对象。自纪元以来,它们应该以毫秒为单位持续存在。 Joda 时间和常规 Java 日期时间都可以为您提供自纪元以来的毫秒数。存储经过的毫秒数,并在您从数据库中读取数据时转换回对象。

持久化重量级 Date 对象而不是 long 有点像使用浮点数来表示货币金额:这通常是一种巨大的代码味道。

【讨论】:

这对于该数据库的非面向对象用户来说似乎不是很有帮助。没有人能够查询该架构并查询今天下达的所有订单。通常我会同意这样的建议,但对我来说这似乎过于 Java 和以对象为中心。 我当然考虑过将日期存储为很长的时间(自纪元以来的毫秒数),但我想做基本的 sql 查询并能够看到可读的日期。此外,我的一些查询正在进行日期计算,我认为数据库不能使用长值而不是日期值来处理。 日期应该以对该数据库最有意义的形式存储。这不是一个 Java 对象,但也不仅仅是一个数字。

以上是关于在 Hibernate 中持久化 Joda DateTime 而不是 Java Date的主要内容,如果未能解决你的问题,请参考以下文章

MySQL DATETIME 精度(joda-time、Hibernate、org.jadira.usertype、hbm2ddl)

休眠 5 的 joda 时间兼容性问题

将 Joda 时间映射到 Cassandra 的日期类型

Hibernate

如何在 Hibernate 中持久化字符串列表?

在 JPA/Hibernate 中持久化映射到 MySQL 视图的实体