JPA 实体、Oracle 10g 和日历类型属性是否存在问题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/82235/
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 17:12:26  来源:igfitidea点击:

Is there a Problem with JPA Entities, Oracle 10g and Calendar Type properties?

javaoraclejpaejb-3.0

提问by huo73

I'm experiencing the following very annoying behaviour when using JPA entitys in conjunction with Oracle 10g.

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

Suppose you have the following entity.

假设您有以下实体。

@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;
    }
}

This entity is mapped to Oracle 10g, so in the DB there will be a table T_ORDERwith a primary key NUMBERcolumn IDand a TIMESTAMPcolumn activationDate.

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

Lets suppose I create an instance of this class with the activation date 15. Sep 2008 00:00AM. My local timezone is CEST which is GMT+02:00. When I persist this object and select the data from the table T_ORDERusing sqlplus, I find out that in the table actually 14. Sep 2008 22:00is stored, which is ok so far, because the oracle db timezone is GMT.

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

But now the annoying part. When I read this entity back into my JAVA program, I find out that the oracle time zone is ignored and I get 14. Sep 2008 22:00 CEST, which is definitly wrong.

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

So basically, when writing to the DB the timezone information will be used, when reading it will be ignored.

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

Is there any solution for this out there? The most simple solution I guess would be to set the oracle dbs timezone to GMT+02, but unfortunatly I can't do this because there are other applications using the same server.

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

We use the following technology

我们使用以下技术

MyEclipse 6.5 JPA with Hibernate 3.2 Oracle 10g thin JDBC Driver

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

采纳答案by davetron5000

You should not use a Calendar for accessing dates from the database, for this exact reason. You should use java.util.Dateas so:

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

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

java.util.Datepoints to a moment in time, irrespective of any timezones. Calendar can be used to format a date for a particular timezone or locale.

java.util.Date指向某个时刻,与任何时区无关。日历可用于格式化特定时区或语言环境的日期。

回答by Jeroen Wyseur

I already had my share of problems with JPA and timestamps. I've been reading in the oracle forumsand please check the following:

我已经遇到了 JPA 和时间戳的问题。我一直在阅读oracle 论坛,请检查以下内容:

  • The field in the database should be TIMESTAMP_TZ and not just TIMESTAMP
  • Try adding the annotation @Temporal(value = TemporalType.TIMESTAMP)
  • If you don't really need the timezone, put in a date or timestamp field.
  • 数据库中的字段应该是 TIMESTAMP_TZ 而不仅仅是 TIMESTAMP
  • 尝试添加注释 @Temporal(value = TemporalType.TIMESTAMP)
  • 如果您真的不需要时区,请输入日期或时间戳字段。