一尘不染

使用Oracle 12的@Temporal(TemporalType.DATE)

hibernate

在我们的数据库中,我们有多个带有日期字段的实体。Oracle认为每个日期都是相同的,带有日期和时间部分。但是,JPA实体通过注释@Temporal进行区分。当我们想省略时间部分时,我们用@Temporal(TemporalType.DATE)注释Date字段,Oracle保存00:00:00,如果不是,我们就不加注释。

例:

@Entity
public class MyEntity implements Serializable {
  private static final long serialVersionUID = 1L;

  @Id
  private long myentityId;

  @Temporal(TemporalType.DATE)
  private Date importantDate; //01.01.2015 00:00:00

  private Date creationDate; //01.01.2015 10:35:51
  ...
}

...
MyEntity me = new MyEntity();
me.setImportantDate(new Date());
me.setCreationDate(new Date());
...

我们从甲骨文11升级到Oracle 12,现在的时间部分 importantDate 不再省略!

我使用完全相同的程序在两个数据库上对此进行了广泛的测试。这实际上破坏了我们的应用程序。

我该怎么做才能恢复以前的行为?


更新1:我缩小了范围:驱动程序ojdbc6 12.1.0.1.0出现了问题,ojdbc6 11.2.0.3.0可以正常工作。(都使用Oracle 12
DB)

这是11.1中解决的时间戳问题的延续吗?(http://www.oracle.com/technetwork/database/enterprise-
edition/jdbc-
faq-090281.html#08_01)


更新2:由于似乎不是Hibernate的问题,所以我用纯JDBC编写了一个示例:

OracleDataSource ods = new OracleDataSource();
...
Connection conn = ods.getConnection();
PreparedStatement ps = conn.prepareStatement("UPDATE MyEntity SET importantDate = ? WHERE myentityId = 4385");
ps.setDate(1, new java.sql.Date(new java.util.Date().getTime()));
ps.execute();
...

在ojdbc6 11.1和ojdbc6 12.1之间切换时,此片段的行为有所不同。


阅读 307

收藏
2020-06-20

共1个答案

一尘不染

我们已与Oracle支持部门取得联系,他们的答复如下(很遗憾,由于需要Oracle支持帐户,因此我无法提供答案的链接):

新行为按预期工作

在JDBC 12.1.0.1中,getDate和setDate不会截断日期的时间部分。此行为与时间部分被截断的JDBC
11.2.0.X不同。根据错误14389749、17228297的更改,这是有意的,并且12c驱动程序的行为正确。

解决方法为我提供了工作:

解决方法#1: 修改应用程序以不插入时间分量(例如,使用静态UtilMethod)

public static Date truncateTime(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); }

解决方法2: 从MOS下载并应用补丁19297927:(My Oracle Support)

  1. 单击补丁和更新选项卡。
  2. 输入上面的补丁号,然后单击“搜索”。
  3. 从列表中单击与您的平台相对应的补丁号
  4. 点击下载按钮下载补丁。
  5. 在下载之前,请阅读所有适用的说明,然后单击“下载”按钮。

After patching replace ojdb7.jar in
%Oracle_Home%\oracle_common\modules\oracle.jdbc_12.1.0 and add
-Doracle.jdbc.DateZeroTime=true to your JVM Arguments

2020-06-20