Joda时间DateTime在数据库中存储不正确

11
我使用org.jadira.usertype:usertype.jodatime:1.9将JodaTime DateTime字段存储到timestamptz列中。 应用程序服务器具有+4时区。 DB服务器+9时区。new DateTime()的结果是${currentTime + 1hour} + 9,其中+9是时区(正确值为${currentTime+5hours)+9)。
我没有找到任何相关主题。 java.util.Date存储正确。
域对象具有以下映射属性:
static mapping = {
    dateCreated sqlType:'timestamptz'
}

如何正确存储日期时间?

7个回答

10

只需设置JPA属性:

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

1
这个应该放在哪个文件里? - dgrant
在你的 persistence.xml 文件中加入 @dgrant。 - Hamish
有没有一种方法可以不使用XML文件来完成这个任务?到目前为止,我的项目都是使用纯注释进行配置的... - Jules

8

我曾经遇到过相同的问题。在配置文件中指定应用程序和数据库区域可以解决这个问题。

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

1
这个应该放在哪个文件里? - dgrant

6

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

但最好使用官方hibernate支持。它可以直接解决问题,因为它使用java.util.Date来持久化DateTime,并且默认情况下正确地持久化java.util.Date


10
官方的Hibernate支持不包括Hibernate 4.0,为此您需要使用UserType。 :-( - drone.ah

1

尝试在JAVA_OPTS上使用 -Duser.timezone=UTC 启动JVM,这样时间就在一个时区中,您可以在此基础上执行操作将其转换为任何其他时区。


这是一个很好的方法 - 但请注意,如果您已经在数据库中存储了另一个时区的日期,则无法这样做。换句话说,对于新项目没有问题,但对于现有数据的项目,请非常小心。 - RedYeti

0

我们正在使用PostgreSQL timestamptz。 - fedor.belov

0

我通过创建其他继承自AbstractVersionableUserType的PersistentDateTime解决了这个问题。

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

0

给Spring Boot用户的一个更新。我能够做到以下几点:

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

我把这个放在我的application.yaml文件里。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接