2

在将 JPA 实体与 Oracle 10g 结合使用时,我遇到了以下非常烦人的行为。

假设您有以下实体。

@Entity
@Table(name = "T_Order")
public class TOrder implements Serializable {
    private static final long serialVersionUID = 2235742302377173533L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Column(name = "activationDate")
    private Calendar activationDate;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Calendar getActivationDate() {
        return activationDate;
    }

    public void setActivationDate(Calendar activationDate) {
        this.activationDate = activationDate;
    }
}

该实体映射到 Oracle 10g,因此在 DB 中将有一个表T_ORDER,其中包含一个主键NUMBERID和一个TIMESTAMPactivationDate

假设我创建了一个带有激活日期的类的实例15. Sep 2008 00:00AM。我的本地时区是 CEST,即GMT+02:00. 当我持久化这个对象并T_ORDER使用 sqlplus 从表中选择数据时,我发现表中实际上14. Sep 2008 22:00是存储的,到目前为止还可以,因为 oracle db 时区是 GMT。

但现在令人讨厌的部分。当我将这个实体读回到我的 JAVA 程序中时,我发现 oracle 时区被忽略并且我得到14. Sep 2008 22:00 CEST,这绝对是错误的。

所以基本上,当写入数据库时​​,将使用时区信息,读取时将被忽略。

有什么解决方案吗?我猜最简单的解决方案是将 oracle dbs 时区设置为GMT+02,但不幸的是我不能这样做,因为有其他应用程序使用同一服务器。

我们使用以下技术

MyEclipse 6.5 JPA 和 Hibernate 3.2 Oracle 10g 瘦 JDBC 驱动程序

4

2 回答 2

2

出于这个确切原因,您不应该使用日历来访问数据库中的日期。你应该java.util.Date这样使用:

@Temporal(TemporalType.TIMESTAMP)
@Column(name="activationDate")
public Date getActivationDate() {
    return this.activationDate;
}

java.util.Date指向一个时刻,与任何时区无关。日历可用于格式化特定时区或区域设置的日期。

于 2008-09-17T16:57:32.093 回答
0

我已经在 J​​PA 和时间戳方面遇到了一些问题。我一直在阅读oracle 论坛,请检查以下内容:

  • 数据库中的字段应该是 TIMESTAMP_TZ 而不仅仅是 TIMESTAMP
  • 尝试添加注释 @Temporal(value = TemporalType.TIMESTAMP)
  • 如果您真的不需要时区,请输入日期或时间戳字段。
于 2008-09-17T12:11:55.837 回答