将JPA实体与Oracle 10g结合使用时,我遇到以下非常令人讨厌的行为。
假设您具有以下实体。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @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,因此在数据库中将有一个表T_ORDER,其主键NUMBER列" ID"和TIMESTAMP列" activationDate"。
假设我创建了一个此类的实例,其激活日期为" 15. Sep 2008 00:00 AM"。我的当地时区是CEST,即GMT + 02:00。当我持久化该对象并使用sqlplus从表T_ORDER中选择数据时,我发现在表中实际上存储了" 14. Sep 2008 22:00",到目前为止,这是可以的,因为oracle db时区是GMT。
但是现在令人讨厌的部分。当我将这个实体读回我的JAVA程序时,我发现oracle时区被忽略了,并得到" 14. Sep 2008 22:00 CEST",这肯定是错误的。
因此,基本上,在写入数据库时??,将使用时区信息,而在读取时将被忽略。
有什么解决办法吗?我猜最简单的解决方案是将oracle dbs时区设置为GMT + 02,但是不幸的是我不能这样做,因为还有其他应用程序使用同一服务器。
我们使用以下技术
MyEclipse 6.5
带有Hibernate 3.2的JPA
Oracle 10g瘦JDBC驱动程序
出于这个确切的原因,您不应使用日历来访问数据库中的日期。 您应该这样使用java.util.Date:
1 2 3 4 5
| @Temporal(TemporalType.TIMESTAMP)
@Column(name="activationDate")
public Date getActivationDate() {
return this.activationDate;
} |
java.util.Date指向时刻,与任何时区无关。 日历可用于格式化特定时区或区域设置的日期。
我已经遇到了JPA和时间戳的问题。 我已经在oracle论坛中阅读了,请检查以下内容:
-
数据库中的字段应该是TIMESTAMP_TZ,而不仅仅是TIMESTAMP
-
尝试添加注释@Temporal(value = TemporalType.TIMESTAMP)
-
如果您确实不需要时区,请在日期或时间戳字段中输入。