休眠 4 和 joda 时间

2022-08-31 15:37:20

他们结婚幸福吗?

我正在使用最新版本的hibernate(4)和1.3版本的joda-time hibernate支持,我也认为这是当前的最新版本。

使用注释时,一切似乎都正常(按预期创建日期列):

@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate")
private LocalDate myDate; 

他们一起使用这些版本是否有任何已知问题?

更新事实证明,列被创建,但无法填充任何数据:

处理程序处理失败;nested exception is java.lang.AbstractMethodError: org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet

它们不兼容,我应该使用用户类型请参阅下面的答案。


答案 1

文档明显缺乏,这意味着写下集成所需的步骤可能对我有所帮助。确保您的库是最新的。

你需要 : [假设你已经休眠了4]

最新版本的乔达时间

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.0</version>
</dependency>

和用户类型库

<dependency>
    <groupId>org.jadira.usertype</groupId>
    <artifactId>usertype.core</artifactId>
    <version>3.0.0.CR1</version>
</dependency>

然后在实体类中使用以下内容(不必是 LocalDateTime,可以是任何可用的持久化类):

import org.joda.time.LocalDateTime;

和列定义:

@Column(name="updated", nullable = false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime updated;

答案 2

我将添加此作为单独的答案,因为在我看来,对于升级到Hibernate 4并且需要迁移到使用jadira的持久时间类型的人来说,这是重要的信息。此页面在休眠4和jodatime的Google搜索结果中排名很高,所以我将在此处添加它。(有关此问题的单独讨论,请参阅:Joda 时间 DateTime 错误地存储在数据库中)

如果您处于 UTC 以外的时区,则需要一个重要的配置才能获得与 joda 时间休眠支持类型相同的行为。默认情况下,jadira 的时态类型的工作方式是在保存到数据库之前将所有值转换为 UTC 时区,并在从数据库加载值时转换回系统的时区。

升级后,我被这个烧伤了,当我在数据库中有很多时间戳和我的确切时区(UTC + 1(夏季时+2))。在升级到 Hibernate 4、1 或 2 小时(取决于时间戳是否在夏季)后加载到数据库中的值中,这意味着所有现有时间戳都错误地显示出来。此外,新的时间戳值存储在具有 UTC 时区的数据库中,导致它们在应用程序中正确显示,但在数据库中错误。总而言之,时区和时间戳一团糟。

因此,为了获得与 joda-times 休眠支持相同的行为(持久保存的日期时间是相关服务器的时区,并且数据库中的时间戳与加载到应用程序中的时间戳相同),必须将以下属性添加到 JPA/Hibernate 配置中(在我的情况下, ):hibernate.properties

jadira.usertype.autoRegisterUserTypes=true
jadira.usertype.databaseZone=jvm
jadira.usertype.javaZone=jvm

这将确保数据库中的时间戳与应用程序的时间戳具有相同的时区,而应用程序时间戳又是 jvm 的时区(在大多数情况下是应用程序服务器的时钟)。

另外,据我所知,-属性消除了对选择常见类型的-注释的需求,其中包括Jodatime类型和.autoRegisterUserTypes@TypeDateTimeLocalDate


推荐