Joda时间DateTime错误地存储在数据库中

时间:2012-04-09 15:16:35

标签: hibernate grails groovy gorm jodatime

我使用DateTime将JodaTime 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?

7 个答案:

答案 0 :(得分:9)

只需设置JPA属性:

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

答案 1 :(得分:8)

我有同样的问题。在config中指定app和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>

答案 2 :(得分:4)

确定。我花了8个小时来解决问题。如果您正在使用usertype项目来持久化JodaTime,则必须将databaseZone类的PersistentDateTime属性设置为等于当前应用程序服务器时区(不是数据库!)。

但最好使用official hibernate support。它解决了这个问题,因为它使用java.utl.Date来保持DateTimejava.util.Date默认正确保留

答案 3 :(得分:1)

尝试使用-Duser.timezone = UTC将JVM启动到JAVA_OPTS,这样时间就在一个区域中,然后您可以对其进行操作以将其转换为您所在的位置。

答案 4 :(得分:0)

费多尔,

我是否正确地假设您正在使用Oracle TIMESTAMP WITH TIME ZONE列? Usertype还不支持这种类型(即使用TIME ZONE),因为JDBC之间的处理方式不同,尽管项目很乐意接受补丁。

Oracle在这里有一些很好的讨论:http://puretech.paawak.com/2010/11/02/how-to-handle-oracle-timestamp-with-timezone-from-java/

答案 5 :(得分:0)

我通过创建其他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);
}
}

答案 6 :(得分:0)

仅是Spring Boot用户的更新。我能够做到以下几点:

spring.jpa.properties.jadira.usertype:
  autoRegisterUserTypes: true
  databaseZone: jvm
  javaZone: jvm

我将其放在我的application.yaml文件中。