我正在使用最新版本的hibernate(4)和版本1.3的joda-time hibernate support,我也相信它是当前的最新版本。
使用注释时,一切似乎都正常(按预期创建日期列):
@Column
@Type(type="org.joda.time.contrib.hibernate.PersistentLocalDate")
private LocalDate myDate;
他们一起使用这些版本有任何已知问题吗?
更新 事实证明,列已创建,但无法填充任何数据:
处理程序处理失败;嵌套异常是java.lang.AbstractMethodError:org.joda.time.contrib.hibernate.PersistentLocalDateTime.nullSafeSet
它们不兼容,我应该使用usertype。请参阅下面的答案。
答案 0 :(得分:96)
明显缺乏文档,这意味着我可能有助于记下集成所需的步骤。确保您的库是最新的。
你需要:[假设你已经有了hibernate4]
joda-time的最新版本
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.0</version>
</dependency>
和usertype lib
<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;
答案 1 :(得分:29)
我将这个作为一个单独的答案添加,因为在我看来,升级到Hibernate 4的任何人都需要迁移到使用jadira的持久时间类型的重要信息。这个页面在hibernate 4和jodatime的谷歌搜索结果中排名很高,所以我会在这里添加它。 (有关此问题的单独讨论,请参阅:Joda time DateTime incorrectly stores in database)
如果您所在的时区不是UTC,则需要一个重要的配置才能获得与joda-time hibernate-support类型相同的行为。 jadira的临时类型默认工作的方式是在持久化到数据库之前将所有值转换为UTC时区,并在从数据库加载值时转换回系统的时区。
升级之后我被这个烧了,当时我在数据库中有很多时间戳和我的确切时区(UTC + 1(夏季时+2))。在升级到Hibernate 4之后加载,1或2小时(取决于时间戳是否在夏令时期间)被添加到数据库中的值,这意味着所有现有时间戳都被错误地呈现。此外,新的时间戳值以UTC时区存储在数据库中,导致它们在应用程序中正确显示,但在数据库中出错。总而言之,是时区和时间戳的热点。
因此,为了获得与joda-times hibernate-support相同的行为(持久化的日期时间是所讨论的服务器的时区,并且数据库中的时间戳与加载到的时间戳相同)应用程序),必须将以下属性添加到JPA / Hibernate配置(在我的例子中,hibernate.properties
):
jadira.usertype.autoRegisterUserTypes=true
jadira.usertype.databaseZone=jvm
jadira.usertype.javaZone=jvm
这将确保数据库中的时间戳与应用程序的时区相同,而后者又是jvm的时区(在大多数情况下是应用程序服务器的时钟)。
另外,根据我的理解,autoRegisterUserTypes
- 属性不需要@Type
- 注释选择常见类型,其中包括Jodatime类型DateTime
和{ {1}}。