在我们的DB中,我们有多个具有日期字段的实体。Oracle认为每个日期都是相同的,有日期和时间部分。然而,JPA实体通过注释@ the来区分。当我们想要省略时间部分时,我们用@Temporal(TemporalType.DATE)注释日期字段,而OracleSave00: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升级到Oracle12,现在不再省略importantDate的时间部分了!
我用完全相同的程序在两个数据库上进行了广泛的测试。这实际上破坏了我们的应用程序。
我能做些什么来恢复以前的行为?
更新1:我缩小了问题范围:驱动程序ojdbc6 12.1.0.1.0有问题,ojdbc6 11.2.0.3.0按预期工作。(都使用Oracle 12 DB)
这是11.1中修正的时间戳问题的延续吗?(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之间切换时,此代码段的行为有所不同。
发布于 2015-11-13 10:24:00
我们已经连接了Oracle支持,他们的答复如下(不幸的是,我无法提供到答案的链接,因为需要Oracle支持帐户):
新行为与预期的一样工作
在JDBC12.1.0.1中,getDate和setDate不截断日期的时间分量。此行为与JDBC11.2.0.X不同,后者截断时间组件。根据bug 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:从下载并应用修补程序19297927 (我的Oracle支持)
修补完之后,在%Oracle_Home%\oracle_common\modules\oracle.jdbc_12.1.0中替换ojdb7.jar并向JVM参数中添加-Doracle.jdbc.DateZeroTime=true
https://stackoverflow.com/questions/33232260
复制相似问题