Время Joda DateTime неправильно хранится в базе данных

Я храню поле JodaTime DateTime в столбце timestamptz, используя org.jadira.usertype:usertype.jodatime:1.9. Сервер приложений имеет +4 часовой пояс. Сервер БД +9 часовой пояс. new DateTime() приводит к ${currentTime+1hour}+9, где +9 - часовой пояс (правильное значение ${currentTime+5hours)+9).

Я не нашел связанных тем. java.util.Date хранится правильно.

Объект домена имеет следующее свойство сопоставления:

static mapping = {
    dateCreated sqlType:'timestamptz'
}

Как я могу правильно хранить DateTime?

Ответ 1

Ok. Я потратил 8 часов, чтобы решить проблему. Если вы используете usertype, чтобы сохранить JodaTime, вам нужно установить свойство databaseZone класса PersistentDateTime равно текущему часовому поясу сервера приложений (не база данных!).

Но лучше использовать официальную поддержку спящего режима. Он решает проблему из коробки, потому что она использует java.utl.Date для сохранения DateTime и java.util.Date по умолчанию сохранена

Ответ 2

Просто установите свойства JPA:

<property name="jadira.usertype.autoRegisterUserTypes"
          value="true"/>
<property name="jadira.usertype.databaseZone"
          value="jvm"/>
<property name="jadira.usertype.javaZone"
          value="jvm"/>

Ответ 3

У меня была такая же проблема. Указание зон приложения и db в конфигурации разрешило проблему.

            <prop key="jadira.usertype.autoRegisterUserTypes">true</prop>
            <prop key="jadira.usertype.databaseZone">America/Los_Angeles</prop>
            <prop key="jadira.usertype.javaZone">America/Los_Angeles</prop>

Ответ 4

Попробуйте запустить JVM с -Duser.timezone = UTC в JAVA_OPTS таким образом, что время находится в одной зоне, и затем вы можете выполнять свои операции над тем, чтобы преобразовать его туда, где вы находитесь.

Ответ 5

Федор,

Можно ли предположить, что вы используете колонку Oracle TIMESTAMP WITH TIME ZONE? Usertype еще не поддерживает этот тип (т.е. С TIME ZONE) из-за обработки JDBC, различающейся между базами данных, хотя проект будет рад принять исправления.

Там есть хорошее обсуждение здесь: http://puretech.paawak.com/2010/11/02/how-to-handle-oracle-timestamp-with-timezone-from-java/

Ответ 6

Я решил эти проблемы, создав другой PersistentDateTime, расширяет AbstractVersionableUserType.

import java.sql.Timestamp;

import org.hibernate.SessionFactory;
import org.hibernate.usertype.ParameterizedType;
import org.jadira.usertype.dateandtime.joda.columnmapper.TimestampColumnDateTimeMapper;
import org.jadira.usertype.spi.shared.AbstractVersionableUserType;
import org.jadira.usertype.spi.shared.IntegratorConfiguredType;
import org.joda.time.DateTime;

public class PersistentDateTime extends AbstractVersionableUserType<DateTime, Timestamp, TimestampColumnDateTimeMapper> implements ParameterizedType, IntegratorConfiguredType {

@Override
public int compare(Object o1, Object o2) {
    return ((DateTime) o1).compareTo((DateTime) o2);
}

@Override
public void applyConfiguration(SessionFactory sessionFactory) {

    super.applyConfiguration(sessionFactory);

    TimestampColumnDateTimeMapper columnMapper = (TimestampColumnDateTimeMapper) getColumnMapper();
    columnMapper.setDatabaseZone(null);
    columnMapper.setJavaZone(null);
}
}