5

我正在编写一个使用 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 异常描述:对象 [oracle.sql.TIMESTAMPTZ@12cbe3f],属于 [class oracle. sql.TIMESTAMPTZ],来自映射 [org.eclipse.persistence.mappings.DirectToFieldMapping[startDateTime-->APPT_EVENT.START_DATE_TIME]] 与描述符 [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 上读到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 异常描述:对象 [12/4/12 7:00 AM],类 [class java.util.Date],来自映射 [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>

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

谢谢!

4

3 回答 3

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"/>
于 2012-12-25T00:41:36.670 回答
1

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

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

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

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

我把这个留给其他可能遇到这个的人。

于 2013-01-03T00:14:14.473 回答
1

在尝试了这里提到的大多数解决方案之后:

  1. 将 ojdbc6.jar 添加到类路径。
  2. 有和没有@TypeConverter 和@Converter。
  3. 在 java.util.Date 和 java.util.Calendar 之间更改实体属性。
  4. 将 eclipselink.target-server 设置为 weblogic。

...仍然存在以下错误:

异常 [EclipseLink-3002] (Eclipse Persistence Services - 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 --> [DatabaseTable(APPT_EVENT)])] ,无法转换为 [class java.util.Date]。

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

于 2013-07-24T03:30:51.457 回答