我正在使用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
一致的方式获取此数据?
(请记住,我只能控制测试代码。我无法更改应用程序代码。)
答案 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,让我走上正轨。)