Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何防止hibernate加载错误的日期?_Java_Hibernate_Postgresql_Date_Tapestry - Fatal编程技术网

Java 如何防止hibernate加载错误的日期?

Java 如何防止hibernate加载错误的日期?,java,hibernate,postgresql,date,tapestry,Java,Hibernate,Postgresql,Date,Tapestry,问题是我从DAO的加载函数中得到了错误的日期 观察到的日期存储在PostgreSQL数据库中(来自用户表的birthdate列),等于1982-03-28。它有时被称为1982-03-27。我从更有经验的用户那里得到了一些提示,他们说这与时区问题有关 错误的值来自java.util.Date类的实例。我通过Calendar类的对象获取它们。当我叫这个小家伙: calendar.getTimeZone().getDisplayName() 它回来了 Central European Time

问题是我从DAO的加载函数中得到了错误的日期

观察到的日期存储在PostgreSQL数据库中(来自用户表的birthdate列),等于1982-03-28。它有时被称为1982-03-27。我从更有经验的用户那里得到了一些提示,他们说这与时区问题有关

错误的值来自java.util.Date类的实例。我通过Calendar类的对象获取它们。当我叫这个小家伙:

calendar.getTimeZone().getDisplayName()
它回来了

Central European Time
“生日”列的类型为:

无时区的生日时间戳

postgresql.conf文件中设置的时区变量的值等于波兰

load方法的内部实现如下所示:

public T load(ID aPrimaryKey, boolean aLock)
{
    if (aPrimaryKey == null) {
        throw new IllegalArgumentException("Parameter aPrimaryKey can't be null!");
    }
    preLoad(aPrimaryKey);
    T entity; if (aLock) {
        entity = _session.load(getEntityClass(), aPrimaryKey, LockMode.UPGRADE);
    } else
        entity = _session.load(getEntityClass(), aPrimaryKey);
    postLoad(entity);

    return entity;
}
我的数据库版本是

基于x86_64-unknown-linux-gnu的PostgreSQL 9.4.4,由gcc(Debian)编译 4.9.2-10)4.9.2,64位

我用

hibernate-core-3.6.0.Final.jar

我的实体类如下所示(几乎没有其他字段):


我将
birthdate
字段的类型更改为
timestamtz
——然后一切看起来都很正常。但是如何在不改变列的数据类型的情况下解决这个问题呢?你有什么建议吗?

我想问题可能是你的系统设置为
CET
,但波兰目前是
CEST
(Pg荣誉DST)

您可以做以下几件事:

  • 使用
    设置时区时区以确保它与您的客户端匹配

  • 选择值时使用时区
    或功能
    时区(区域,时间戳)
    ,以匹配客户端

  • 选择时将值强制转换为
    timestamptz
    ,以便保留TZ信息(实际上不确定此信息)

但实际上,总是使用
timestamptz
来存储时间要好得多

要回答评论中的问题,只需将
timestamp/tz
值转换为
date
类型(
birthdate::date
)<代码>日期
s没有时间信息,并且不依赖于时区,因此您将始终按原样获取值


这实际上可能更有意义-您可能希望看到原始时区中的出生日期(即用户输入的日期),而不是转换为当前的TZ。

PG如何将其存储为时间戳而不是日期?奇怪的您可以更改列定义以将其存储为日期而不是时间戳吗?@NeilMcGuigan我可以,但数据库中已经有几千个用户,因此我必须更改所有用户的出生日期(我将在PostgreSQL中检查日期与时间戳的区别,因为我不确定如何在这两种类型之间转换)。
import javax.persistence.Column;

@javax.persistence.Entity
@javax.persistence.Table(name="User")
@javax.persistence.SequenceGenerator(name="userId", sequenceName="user_id_seq", allocationSize=1)
public class User {

   @javax.persistence.Id
   @Column(name="Id", nullable=false)
   @javax.persistence.GeneratedValue(strategy=javax.persistence.GenerationType.AUTO, generator="userId")
   private long id;

   @Column(name="Name")
   private String firstName;

   public User(String firstName, java.util.Date birthDate, java.util.Date registrationDate)
   {
       this.firstName = firstName;
       this.birthDate = birthDate;
       this.registrationDate = registrationDate;
   }

   @Column(name="BirthDate")
   @javax.persistence.Temporal(javax.persistence.TemporalType.DATE)
   private java.util.Date birthDate;

   @Column(name="RegistrationDate", nullable=false)
   @javax.persistence.Temporal(javax.persistence.TemporalType.TIMESTAMP)
   private java.util.Date registrationDate;

   public String toString()
   {
       return firstName + " should clean himself...";
   }

   public User() {}
}