Java 比较hibernate映射的日期?

Java 比较hibernate映射的日期?,java,hibernate,date,Java,Hibernate,Date,如何使用Hibernate将日期从java对象映射到数据库?我尝试了不同的方法,但我对它们不满意。为什么?让我解释一下我的问题。我有以下类[1],包括我调用的主方法和以下映射[2]。当您查看控制台输出时,您可以看到这种方法的问题 假的 假的 一, -一, 1224754335648 1224754335000 2008年10月23日星期四11:32:15 CEST Clock@67064 正如您所看到的,虽然to日期应该是相等的,但它们并不完全相等,因此如果不使用返回值getTime来进行比较,

如何使用Hibernate将日期从java对象映射到数据库?我尝试了不同的方法,但我对它们不满意。为什么?让我解释一下我的问题。我有以下类[1],包括我调用的主方法和以下映射[2]。当您查看控制台输出时,您可以看到这种方法的问题

假的

假的

一,

-一,

1224754335648

1224754335000

2008年10月23日星期四11:32:15 CEST

Clock@67064

正如您所看到的,虽然to日期应该是相等的,但它们并不完全相等,因此如果不使用返回值
getTime
来进行比较,就很难做到这一点。我还尝试在映射中使用java.sql.Date、Timestamp和Date代替Timestamp,但没有成功

我想知道为什么最后三位数字是零,这是一个hibernate还是java问题,还是我自己的愚蠢

谢谢你的阅读

[1]

[2]



显然,目标RDBMS上的时间戳类型(顺便说一句,您使用的是什么?)不会存储毫秒。请尝试找到另一种本机类型,或者将您的时间映射到其他类型,例如long=ms-since-epoch。

SQL Server以3毫秒的精度存储日期时间,这肯定会导致您看到的问题。这样做的一个后果是,Java中的23:59:59.999最终成为SQL Server中的第二天。我从来没有遇到过Oracle、Informix或MySQL方面的问题,但其他数据库的精确度也可能较低。您可以通过使用Hibernate自定义类型来解决这个问题。当您写出日期值时,您必须舍入到低于基础数据库精度的精度。在Hibernate文档中搜索UserType,您将更改nullSafeSet方法以进行舍入。

MySql日期时间精度仅为秒。Java日期精度为毫秒。 这就是为什么最后三位数字在被放入数据库后是零

在您的原始日期执行此操作:

date=date.setTime((date.getTime()/1000)*1000)

这会将其设置为最后一秒,然后所有比较都将匹配

(顺便说一句, System.out.println(fromDBClock.toString()); 应该是
System.out.println(fromDBClock.date.toString());

Personnaly,我使用名为DateUtils的Apache commons lang包类截断POJO对象中收到的每个日期

请参阅[Apache commons站点][1]


[1] :,int)

您使用的目标RDBMS是什么?不同的数据库对次秒时间戳解析的支持程度不同。当您从数据库获取时钟时,您已将id硬编码为1,您确定它与刚才保存的值对应吗?我使用MySql数据库。你指的是另一种本机类型吗?有些数据库有多种日期/时间数据类型。根据doc,MySQL中没有高精度的日期数据类型:(您唯一简单的选择是将datetime映射为毫秒到长的时间。如果您创建自定义类型,甚至转换都将是自动的。我也使用MySql。这就是问题发生的地方。嗯……奇怪。也许我必须设置一些
选项来允许这种精度?!快速解决方法:
org.apache.commons.lang3.time.DateUtils.truncatedEquals(a,b,Calendar.SECOND);
public class Clock {

    int id;
    java.util.Date date;

    public static void main(String[] args) {
        HibernateUtil.init();
        HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();

        Clock clock = new Clock();
        clock.date = new java.util.Date();

        HibernateUtil.getSessionFactory().getCurrentSession().saveOrUpdate(clock);
        HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();

        HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();

        Clock fromDBClock = (Clock)HibernateUtil.getSessionFactory()
                        .getCurrentSession().get(Clock.class, 1);

        System.out.println(clock.date.equals(fromDBClock.date));
        System.out.println(fromDBClock.date.equals(clock.date));

        System.out.println(clock.date.compareTo(fromDBClock.date));
        System.out.println(fromDBClock.date.compareTo(clock.date));

        System.out.println(clock.date.getTime());
        System.out.println(fromDBClock.date.getTime());

        System.out.println(clock.date.toString());
        System.out.println(fromDBClock.toString());

        HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();

        HibernateUtil.end();
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public java.util.Date getDate() {
        return date;
    }

    public void setDate(java.util.Date date) {
        this.date = date;
    }


}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    <class name="Clock" table="CLOCK">
        <id name="id" column="CLOCK_ID">
            <generator class="native"/>
        </id>
        <property name="date" type="timestamp"/>


    </class>

</hibernate-mapping>