2016-03-30 3 views
0

Проблема в том, что я получаю неправильную дату из функции загрузки DAO.Как предотвратить спящий режим загрузки неправильных дат?

Наблюдаемая дата хранится в базе данных PostgreSQL (из столбца даты рождения из таблицы пользователя) и равна 1982-03-28. Его иногда выбирают как 1982-03-27. Я получил несколько советов от более опытных пользователей, и они говорят, что это как-то связано с проблемами часового пояса.

Неверные значения взяты из экземпляра класса java.util.Date. Я получаю их с помощью объекта класса Calendar. Когда я называю этот маленький один:

calendar.getTimeZone().getDisplayName() 

возвращает

Central European Time 

типа Колонном BirthDate является:

дата рождения TIMESTAMP без временной зоны

Значение из переменная часового пояса, установленная в файле postgresql.conf, равна Польше.

внутренняя реализация метод загрузки выглядит следующим образом:

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

Моя версия базы данных

PostgreSQL 9.4.4 на x86_64-неизвестно-Linux-гну, составленный НКУ (Debian 4,9 .2-10) 4.9.2, 64-битный

Я использую

гибернации-ядро-3.6.0.Final.jar

Мой класс объект выглядит следующим образом (имеет несколько полей):

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() {} 
} 

Я изменил тип birthdate поля TIMESTAMPTZ - тогда все, кажется, работает хорошо. Но как решить проблему без изменения типа данных столбца? Есть ли у вас какие-либо советы?

+0

Как PG хранит его как метку времени, а не дату? Weird. Можете ли вы изменить определение столбца, чтобы сохранить его как дату, а не метку времени? –

+0

@NeilMcGuigan Я мог бы, но у меня уже есть несколько тысяч пользователей в базе данных, поэтому мне пришлось бы менять даты рождения для всех из них (я буду проверять, как Date отличается от Timestamp в PostgreSQL, потому что я не очень уверен, как конвертировать между этими двумя типами). – y434y

ответ

0

Я думаю, проблема в том, что ваша система настроена на CET, но в настоящее время Польша находится на CEST (и Pg honors DST).

Пару вещей, которые вы можете сделать:

  • Использование SET TIME ZONE timezone; в начале каждой сессии, чтобы убедиться, что он соответствует клиенту.

  • Использовать AT TIME ZONE при выборе значений - или функции timezone(zone, timestamp) - для соответствия клиенту.

  • При выборе значения значение timestamptz, поэтому информация TZ сохраняется (на самом деле не уверен в этом).

Но на самом деле, это гораздо лучше всегда использовать timestamptz для хранения времени.

Чтобы ответить на ваш вопрос с комментариями, вы можете просто указать timestamp/tz значениям date (birthdate::date). date s не имеют информации о времени и не зависят от часовой пояс, поэтому вы всегда получите значение as-is.

Возможно, это имеет смысл - вы, вероятно, знаете, что do хотят видеть даты рождения в их исходных часовых поясах (то есть, когда пользователи вводили их), а не преобразовывались в текущий TZ.

Смежные вопросы