Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.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
Hibernate在将Java日历对象读写到SQL时间戳时使用哪个时区?_Java_Sql_Hibernate_Timestamp - Fatal编程技术网

Hibernate在将Java日历对象读写到SQL时间戳时使用哪个时区?

Hibernate在将Java日历对象读写到SQL时间戳时使用哪个时区?,java,sql,hibernate,timestamp,Java,Sql,Hibernate,Timestamp,将Java对象写入SQL列时,它会将日期、计算机日期或日历对象(或其他)中指定的日期调整到哪个时区 当Hibernate将时间戳读入calendar对象时,它将日期转换到哪个时区 当Hibernate将Java日历对象写入SQL时间戳列时,它会将日期、计算机日期或日历对象(或其他)中指定的日期调整到哪个时区 Hibernate 3.x在日历类型中使用以下内容(请参阅): 所以Hibernate使用日历的时区 当Hibernate将时间戳读入calendar对象时,它将日期转换到哪个时区 好的,再

将Java对象写入SQL列时,它会将日期、计算机日期或日历对象(或其他)中指定的日期调整到哪个时区

当Hibernate将时间戳读入calendar对象时,它将日期转换到哪个时区

当Hibernate将Java日历对象写入SQL时间戳列时,它会将日期、计算机日期或日历对象(或其他)中指定的日期调整到哪个时区

Hibernate 3.x在
日历类型中使用以下内容(请参阅):

所以Hibernate使用日历的时区

当Hibernate将时间戳读入calendar对象时,它将日期转换到哪个时区

好的,再次让我们看看
CalendarType
类:

public Object get(ResultSet rs, String name) throws HibernateException, SQLException {

    Timestamp ts = rs.getTimestamp(name);
    if (ts!=null) {
        Calendar cal = new GregorianCalendar();
        if ( Environment.jvmHasTimestampBug() ) {
            cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) );
        }
        else {
            cal.setTime(ts);
        }
        return cal;
    }
    else {
        return null;
    }

}
因此,Hibernate使用默认时区中的当前时间和默认语言环境构建一个默认的GregoriaCalendar


作为旁注,我强烈建议阅读以下问题:


我刚刚花了6个小时在一个类似的问题上,我想我会在这里记录下来。Hibernate确实使用JVM时区,但可以通过如下扩展日历类型来更改它:

public class UTCCalendarType extends CalendarType {

    private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

    /**
     * This is the original code from the class, with two changes. First we pull
     * it out of the result set with an example Calendar. Second, we set the new
     * calendar up in UTC.
     */
    @Override
    public Object get(ResultSet rs, String name) throws SQLException {
        Timestamp ts = rs.getTimestamp(name, new GregorianCalendar(UTC));
        if (ts != null) {
            Calendar cal = new GregorianCalendar(UTC);
            cal.setTime(ts);
            return cal;
        } else {
            return null;
        }
    }

    @Override
    public void set(PreparedStatement st, Object value, int index) throws SQLException {
        final Calendar cal = (Calendar) value;
        cal.setTimeZone(UTC);
        st.setTimestamp(index, new Timestamp(cal.getTime().getTime()), cal);
    }
}
这里的秘方是:

  rs.getTimestamp(name, new GregorianCalendar(UTC));

这会将时区从结果集转换为所需的任何时区。因此,我所做的就是将这种类型与任何UTC日历和本地时间的标准Hibernate类型一起使用。工作起来很流畅…

如果您不想自己编写代码,可以使用开源库
DbAssist
。应用此修复后,数据库中的日期将由JDBC处理,然后作为UTC休眠,因此您甚至不必更改entitiy类

例如,如果您在Hibernate 4.3.11中使用JPA注释,请添加以下Maven依赖项:

<dependency>
    <groupId>com.montrosesoftware</groupId>
    <artifactId>DbAssist-4.3.11</artifactId>
    <version>1.0-RELEASE</version>
</dependency>

如果您想了解有关如何为不同的Hibernate版本(或HBM文件)应用修复程序的更多信息,请参阅。您还可以在本文中阅读有关时区转换问题的更多信息。

默认情况下,由JDBC驱动程序决定使用哪个时区。通常,除非将JDBC驱动程序配置为使用自定义时区,否则将使用JVM时区

如果要控制使用的时区,可以在JVM级别设置时区。如果希望JVM时区与数据库使用的时区不同,则需要使用Hibernate 5.2配置属性:

<property name="hibernate.jdbc.time_zone" value="US/Eastern"/>


相关问题:似乎提供了解决方案。回答得不错!直接从“源头”!出于好奇,代码所指的JVM时间戳bug是什么?@Derek thejavadoc说这个JVM有IBMJDK1.3.1吗。错误是
newtimestamp(x).getTime()=x
。有趣的是,与您引用的版本相比,Hibernate类型类的当前版本更通用,更不直接(因此,更难理解)。不过,基本的最低级别代码基本相同,只是现在Hibernate不再将日历传递给
setTimestamp()
。虽然在的文档中没有说明,但我猜此方法仍然使用默认时区。@Derek您指的是什么“当前”版本,3.6.0.Final?它只是创建一个
日历
,默认情况下使用默认时区。您所要做的就是将
日历
对象上的时区更改为您喜欢的任何时区。内部存储器只是一个毫秒计数器。更改时区只会导致日历上的
get
方法以不同方式转换毫秒。您好@markthegrea,hibernate是否需要进行任何配置更改,以使hibernate采用自定义UTCCalendarType而不是基类CalendarType?非常感谢。。。耶。。!!!是的!
<property name="createdAt" type="com.montrosesoftware.dbassist.types.UtcDateType" column="created_at"/>
<property name="hibernate.jdbc.time_zone" value="US/Eastern"/>