JPA 2.0 Oracle DATE 有空时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3469018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 21:14:31  来源:igfitidea点击:

JPA 2.0 Oracle DATE has null time

oraclehibernateormdatejpa

提问by Griff

This seems like such a bonehead question, but I've been chasing my tail around a tree all day. I have a Struts 2 + Spring3/JPA/Hibernate application that inserts a large set into the DB. In the set is a Java util date. I've checked the date just before the Dao inserts the rows and all the dates have the correct times. After insert, all the rows in the Oracle DB have no time, just the date. It's as if the time is truncated, but no errors appear in the transaction.

这似乎是一个愚蠢的问题,但我一整天都在绕着树追我的尾巴。我有一个 Struts 2 + Spring3/JPA/Hibernate 应用程序,它将一个大集合插入到数据库中。集合中有一个 Java util 日期。我在 Dao 插入行之前检查了日期,并且所有日期的时间都正确。插入后,Oracle DB 中的所有行都没有时间,只有日期。就好像时间被截断了,但交易中没有出现错误。

I thought before I posted any code, I would ask the question to see if someone could suggest something I may have been overlooking? The DB is Oracle 10g. JPA 2.0. The Column has the annotation on it:

我想在发布任何代码之前,我会问这个问题,看看是否有人可以提出一些我可能忽略的问题?数据库是 Oracle 10g。JPA 2.0。列上有注释:

@Column(name = "READING_DATE")
@Temporal(TemporalType.DATE)
private Date readingDate;

Setting the Column type to TemporalType.TIMESTAMP results in a Hibernate exception

将 Column 类型设置为 TemporalType.TIMESTAMP 会导致 Hibernate 异常

column READING_DATE. Found: date, expected: timestamp

Any/all replies are appreciated.

任何/所有答复表示赞赏。

回答by Pascal Thivent

For this kind of problems, it usually helps to provide the version of the JDBC driver and the dialect you're using.

对于此类问题,提供 JDBC 驱动程序的版本和您使用的方言通常会有所帮助。

Anyway, my understanding is that you actually want the following mapping (for DATE andTIME):

无论如何,我的理解是您实际上需要以下映射(用于日期时间):

@Column(name = "READING_DATE")
@Temporal(TemporalType.TIMESTAMP)
private Date readingDate;

And the problem you're facing is somehow related to the madness introduced by Oracle with version 9.2, see What is going on with DATE and TIMESTAMP?(in short, they introduced a TIMESTAMPcolumn and changed the mapping of the DATESQL type, read the FAQ). There are several options to solve it (I am of course assuming you are using a TemporalType.TIMESTAMPmapping):

您面临的问题在某种程度上与 Oracle 9.2 版引入的疯狂有关,请参阅DATE 和 TIMESTAMP 发生了什么?(简而言之,他们引入了一个TIMESTAMP列并更改了DATESQL类型的映射,阅读FAQ)。有几个选项可以解决它(我当然假设您正在使用TemporalType.TIMESTAMP映射):

Either use a TIMESTAMPcolumn type(I don't mean TemporalType.TIMESTAMPhere, I really mean the column type on the DB side). But if you don't need nanosecond precision, this is not the best choice.

要么使用TIMESTAMP列类型(我不是TemporalType.TIMESTAMP在这里的意思,我的意思是数据库端的列类型)。但如果您不需要纳秒级精度,这不是最佳选择。

Or set the oracle.jdbc.V8Compatible=truecompatibility mode, either as system property or as a connection property:

或者设置oracle.jdbc.V8Compatible=true兼容模式,作为系统属性或连接属性:

<property name="hibernate.connection.oracle.jdbc.V8Compatible">true</property>

Yes, you can set arbitrary connection properties like this. From the Hibernate documentation:

是的,您可以像这样设置任意连接属性。从休眠文档:

3.3. JDBC connections

...

Arbitrary connection properties can be given by prepending "hibernate.connection" to the connection property name. For example, you can specify a charSetconnection property using hibernate.connection.charSet.

3.3. JDBC 连接

...

可以通过在连接属性名称前添加“hibernate.connection”来给出任意连接属性。例如,您可以使用 指定charSet连接属性hibernate.connection.charSet

Or use Oracle JDBC 11.1 driver (they "fixed" the problem by reverting the change). This is IMO the ideal solution (the V8Compatiblestuff is deprecated).

或者使用 Oracle JDBC 11.1 驱动程序(他们通过恢复更改“修复”了问题)。这是 IMO 的理想解决方案(这些V8Compatible东西已被弃用)。

Related issue

相关问题

回答by prashant thakre

Use ojdbc6.jar and use the below code against hibernate 3.3 set timestamp instead of java.sql.date or java.util.date

使用 ojdbc6.jar 并使用以下代码针对 hibernate 3.3 设置时间戳而不是 java.sql.date 或 java.util.date

@Id
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "TDATE", length = 7)
public Date getTdate() {
    return this.tdate;
}