java - @Temporal(TemporalType.DATE) 与 Oracle 12

标签 java oracle hibernate jpa oracle12c

在我们的数据库中,我们有多个带有日期字段的实体。 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());
...

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

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

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


更新 1: 我缩小了问题范围:驱动程序 ojdbc6 12.1.0.1.0 有问题,ojdbc6 11.2.0.3.0 按预期工作。 (均使用 Oracle 12 数据库)

这是 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 之间切换时表现不同。

最佳答案

我们已经联系了 Oracle 支持,他们的回复如下(很遗憾,我无法提供答案链接,因为需要 Oracle 支持帐户):

新行为按预期工作:

In JDBC 12.1.0.1, getDate and setDate do not truncate the time component of the date. This behavior is different to JDBC 11.2.0.X, where the time component is truncated. As per bug 14389749, 17228297 this change is deliberate and the 12c driver's behavior is correct.

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

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

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

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

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

修补后替换 %Oracle_Home%\oracle_common\modules\oracle.jdbc_12.1.0 中的 ojdb7.jar 并将 -Doracle.jdbc.DateZeroTime=true 添加到您的 JVM参数

关于java - @Temporal(TemporalType.DATE) 与 Oracle 12,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33232260/

相关文章:

sql - Oracle 10g 中的可选条件

java - 如何从 hibernate session 中获取 jdbc 连接?

java - 上下文是只读的

java - Tomcat API 与其他 API

linux - 通过sh运行ddl文件

java - JPA/Hibernate : java. sql.SQLException:JDBC 调用中的参数无效:参数索引超出范围

hibernate - Hibernate中Set和Bag的区别

Java - Arraylist/Hash 映射 问题

java - 在非开发模式下运行 GWT + App Engine

java - MyEclipse,Java - Web 应用程序新手