4

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

错误的

错误的

1

-1

1224754335648

1224754335000

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

时钟@67064

正如您所看到的,截止日期并不完全相等,尽管它们应该是相等的,因此很难在没有返回值的情况下比较它们getTime。我还尝试了 java.sql.Date、Timestamp 和 date 而不是映射中的时间戳,但没有成功。

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

感谢您的阅读。

[1]

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


}

[2]

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

4 回答 4

3

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

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

日期 = date.setTime((date.getTime() / 1000) * 1000);

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

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

于 2008-10-23T20:44:21.133 回答
2

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

于 2008-10-23T16:45:05.890 回答
1

显然,目标 RDBMS 上的 TIMESTAMP 类型(顺便说一句,您在使用什么?)不存储毫秒。尝试找到另一种可以执行此操作的本机类型,或者将您的时间映射到其他内容上,例如 long = ms-since-epoch。

于 2008-10-23T10:24:37.700 回答
0

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

请参阅 [Apache 公共站点][1]

[1]:http ://commons.apache.org/lang/api/org/apache/commons/lang/time/DateUtils.html#truncate(java.util.Date , int)

于 2008-10-28T16:51:17.037 回答