【问题标题】:TimeZone Error with EclipseLink and Oracle DBEclipseLink 和 Oracle DB 的时区错误
【发布时间】:2012-12-11 01:34:49
【问题描述】:

我正在编写一个将 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 异常描述:类 [class oracle.sql.TIMESTAMPTZ] 的对象 [oracle.sql.TIMESTAMPTZ@12cbe3f],来自映射 [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 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 异常描述:对象 [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>

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

谢谢!

【问题讨论】:

    标签: jpa oracle11g jpa-2.0 eclipselink


    【解决方案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"/>
    

    【讨论】:

    • 嗨,我试过了,但仍然遇到同样的错误。实际上,使用新的转换器注释,当我持久保存到数据库时它也会引发错误,而没有转换器注释,我可以使用时区保存到数据库,而不是从中检索数据。我也在使用 Glassfish 3.1.2.2。我尝试从 EclipseLink 2.3.2 更新到 2.3.3 但仍然没有运气。感谢您尝试提供帮助。
    • 当然。使用注释保存时的错误是:异常 [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]。
    • 我将信息添加到主帖中。谢谢!
    • 另外,经过进一步调查,看起来没有注释,它正在工作,因为时区实际上并没有被传递。查看日志中的 SQL 调用时,它只是传递了日期和时间。 Oracle DB 必须自动将服务器的时区附加到该值。
    • 我将朝着不同的方向前进,并将数据库中的所有内容存储为 UTC 时间,然后在显示回客户端时在业务逻辑中进行时区转换。不过,我确实相信您的解决方案是正确的,而且我可能只是遇到了一些配置问题。
    【解决方案2】:

    我能够弄清楚这一点,这实际上是由于我的疏忽造成的。 我需要将 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 会在这个版本中自动转换它。 您还需要使用日历,而不是日期,以便您可以检索时区信息。

    我将把它留给可能遇到这种情况的其他人。

    【讨论】:

      【解决方案3】:

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

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

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

      异常 [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[...]] 带描述符 [关系描述符(com.ntst.caremanager.server.entities.ApptEvent --> [DatabaseTable(APPT_EVENT)])],无法转换为 [class java.util.Date]。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-17
        • 1970-01-01
        • 2021-09-12
        • 2013-08-31
        • 2016-04-20
        • 2017-10-08
        • 2017-09-14
        相关资源
        最近更新 更多