2015-10-20 42 views
3

在我们的数据库中,我们有多个具有日期字段的实体。 Oracle将每个日期看作相同的日期和时间部分。然而,JPA实体通过annotaton @Temporal区分。当我们想省略时间部分时,我们使用@Temporal(TemporalType.DATE)和Oracle对日期字段进行注释,如果没有,则保存00:00:00,我们只是不加注释。@Temporal(TemporalType.DATE)与Oracle 12

例子:

@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: 由于休眠似乎并不成为问题,我写用纯JDBC一个例子:ojdbc6 11.1和ojdbc6之间切换时

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(); 
... 

该片段表现不同12.1。

+0

之后你有没有在你的应用程序更新Oracle驱动程序呢? –

+1

您使用的是哪个版本的Hibernate?你在使用['Oracle12cDialect'](https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/dialect/Oracle12cDialect.html)吗? – Tunaki

+0

我们仍然使用org.hibernate.dialect.Oracle10gDialect和OJDBC7驱动程序。现在尝试新的方言。 – Thomas

回答

1

我们conntacted了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. 下载前阅读所有适用的注释,然后点击下载按钮。

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

+0

感谢您的详细信息。当Oracle支持告诉我们,行为如预期的那样,Apache的Hibernate团队没有回应,我们实施了触发器的解决方法以备将来保存。 – Thomas