Hibernate在时间返回类型中不一致(Date与Timestamp)

时间:2017-07-27 01:33:22

标签: java sql hibernate date

我正在使用Hibernate在内存数据库的H2上编写测试代码。我有两个配置几乎相同的项目。在每个测试代码中,测试代码从模型类自动构建数据库模式。两个类都以相同的方式定义数据类型:

@Temporal(TemporalType.TIMESTAMP)
@Column("MY_DATE")
private java.util.Date myDate;

从hibernate调试日志中,我可以看到为两个项目创建的列的类型相同:

create table MY_TABLE (
    ...
    MY_DATE timestamp,
    ...
)

测试模型总是被赋予java.sql.Date

类型的对象

出于某种原因,在一个项目中,当我使用Hibernate查询检索数据时,类型为java.sql.Date,而在另一个项目中,它为java.sql.Timestamp

可能导致这种行为差异的原因是什么?如何以java.sql.Date一致的方式获取此数据?

(请记住,我只能控制测试代码。我无法更改应用程序代码。)

2 个答案:

答案 0 :(得分:2)

我不确定为什么他们会以不同的方式回来 - 您是否在两个项目之间的所有类似日期字段中看到此行为?也就是说 - 即使他们回来的方式不同,你提到你想要将它们一致地恢复为java.sql.Date - 这不是它们的映射方式。基于您应该期望的映射的正确类型是java.sql.Timestamp。如果您需要java.sql.Date,则应使用@Temporal(TemporalType.DATE)

无论哪种方式 - 在您的代码中,您只应针对java.util.Date进行编码,而不是针对基础java.sql.*类。

更理想的情况是,如果您使用的是Java 8,则可以使用java.time.LocalDateTime(或其等效区域划分),否则org.joda.LocalDateTime使用java.util.Date

java.sql.Date和{{1}}是噩梦的恶人:)

答案 1 :(得分:0)

执行Hibernate查询时,如果它显示java.sql.Date实例,则它是在Hibernate会话中缓存的实例,实际上并未从持久数据中重新组装。当它返回java.sql.Timestamp实例时,实际上是根据Temporal(TemporalType.TIMESTAMP)从持久数据中汇总的。要始终获得Timestamp,请确保在查询数据之前使用Session.evict。在问题的参数范围内,不可能始终获得Date实例(即,它需要更改应用程序代码)。

(谢谢,并赞成Ben,让我走上正轨。)