EclipseLink和Oracle DB的TimeZone错误

时间:2012-12-24 18:24:41

标签: jpa oracle11g jpa-2.0 eclipselink

我正在编写一个使用JPA和GlassFish 3.1.2.2以及EclipseLink 2.3.2的应用程序。我正在使用Oracle DB 11g并尝试使用TIMESTAMPTZ字段类型以时区存储日期和时间。

通过我的设置,我可以将时区的日期和时间保存到数据库中。 (更新 - 实际上,在查看实际的SQL调用时,它只传递日期和时间.Oracle必须在保存到数据库时附加时区。)

然而,在检索数据时,我遇到以下异常:

  

异常[EclipseLink-3002](Eclipse Persistence Services - 2.3.2.v20111125-r10461):org.eclipse.persistence.exceptions.ConversionException   异常描述:来自[org.eclipse.persistence.mappings.DirectToFieldMapping [startDateTime - > APPT_EVENT.START_DATE_TIME]]的[class oracle.sql.TIMESTAMPTZ]类的对象[oracle.sql.TIMESTAMPTZ@12cbe3f] descriptor [RelationalDescriptor(com.ntst.caremanager.server.entities.ApptEvent - > [DatabaseTable(APPT_EVENT)])]无法转换为[class java.util.Date]。

以前有没有人见过这个?这就是我的实体类中的'startDateTime'字段的设置方式:

@Column(name = "START_DATE_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date startDateTime;

START_DATE_TIME在DB中使用以下DDL定义:

"START_DATE_TIME" TIMESTAMP (6) WITH TIME ZONE

我已阅读eclipselink wiki here,EclipseLink本身支持oracle的TIMESTAMPTZ,无需任何转换。我也尝试在我的实体类中使用“日历”类型而不是“日期”时间。

更新: 也尝试了这个

@Convert("timestamptz")
@TypeConverter(name="timestamptz", dataType=TIMESTAMPTZ.class)
@Column(name = "START_DATE_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date startDateTime;

还没有运气。奇怪的是,随着转换器的添加,持久到数据库不再有效。尝试保存值时出现此错误。

  

异常[EclipseLink-3002](Eclipse Persistence Services - 2.3.3.v20120629-r11760):org.eclipse.persistence.exceptions.ConversionException   异常描述:类[类java.util.Date]的对象[12/4/12 7:00 AM]来自映射[org.eclipse.persistence.mappings.DirectToFieldMapping [startDateTime - > APPT_EVENT.START_DATE_TIME]使用描述符[RelationalDescriptor(com.ntst.caremanager.server.entities.ApptEvent - > [DatabaseTable(APPT_EVENT)])],无法转换为[class oracle.sql.TIMESTAMPTZ]。

尝试检索值时,我仍然遇到同样的错误。 我也尝试将Glassfish更新到EclipseLink 2.3.3并得到了同样的错误。

这是我的持久性文件:

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="CM-warPU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>CMDEV</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
  <property name="eclipselink.logging.level" value="FINE"/>
  <property name="eclipselink.logging.parameters" value="true"/>
  <property name="eclipselink.target-server" value="SunAS9"/>
</properties>

之前有没有人见过这个问题,或者看到我可能犯过的任何错误?

谢谢!

3 个答案:

答案 0 :(得分:1)

您需要指定转换器

@Convert("timestamptz")
@TypeConverter(name="timestamptz", dataType=TIMESTAMPTZ.class)
@Column(name = "START_DATE_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date startDateTime;

您还需要配置服务器平台,以便EclipseLink可以获取JDBC连接以正确执行转换。这可以在persistence.xml中完成

<property name="eclipselink.target-server" value="WebLogic"/>

答案 1 :(得分:1)

我能够弄清楚这一点,实际上是由于我的遗漏。 我需要将ojdbc6.jar文件添加到glassfish的domains \ domain1 \ lib \ ext \目录中,以便EclipseLink可以找到oracle.sql.timestamptz类型。

就是这样。完成后,我可以使用以下方法检索时区数据并将其存储到Oracle数据库:

@Column(name = "START_DATE_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Calendar startDateTime;

无需使用@TypeConverter或@Converter,因为EclipseLink会自动在此版本中对其进行转换。 您还需要使用日历,而不是日期,以便您可以检索TimeZone信息。

对于可能遇到此问题的其他人,我会把它留下来。

答案 2 :(得分:1)

尝试了这里提到的大部分解决方案之后:

  1. 将ojdbc6.jar添加到类路径中。
  2. 有和没有@TypeConverter和@Converter。
  3. 将实体属性更改为java.util.Date和java.util.Calendar。
  4. 将eclipselink.target-server设置为weblogic。
  5. ......仍然存在以下错误:

      

    异常[EclipseLink-3002](Eclipse持久性服务 -   2.3.2.v20111125-r10461):org.eclipse.persistence.exceptions.ConversionException异常   描述:类的对象[oracle.sql.TIMESTAMPTZ@12cbe3f]   [class oracle.sql.TIMESTAMPTZ],来自映射   [org.eclipse.persistence.mappings.DirectToFieldMapping [...]   带描述符   [RelationalDescriptor(com.ntst.caremanager.server.entities.ApptEvent    - &GT; [DatabaseTable(APPT_EVENT)])],无法转换为[类java.util.Date]。

    当我将eclipselink.target-database从“Oracle”更改为“Oracle11”时,我终于让它工作了(在我的实体中没有@converter和java.util.Calendar)。