Сравнение дат в спящем режиме? - PullRequest
4 голосов
/ 23 октября 2008

Как я могу отобразить дату из Java-объекта в базу данных с Hibernate? Я пробую разные подходы, но я не доволен ими. Зачем? Позвольте мне объяснить мою проблему. У меня есть следующий класс [1], включая основной метод, который я вызываю, и со следующим отображением [2]. Проблема с этим подходом вы можете увидеть, когда посмотрите на вывод консоли.

ложь

ложь

1

-1 * * +1010

1224754335648

1224754335000

Чт, 23 октября 11:32:15 CEST 2008

Часы @ 67064

Как вы можете видеть, даты to не совсем равны, хотя они и должны, поэтому трудно сравнивать их, не балуясь возвращаемым значением getTime. Я также пробовал java.sql.Date, Timestamp и date вместо timestamp в отображении, но безуспешно.

Интересно, почему последние три цифры равны нулю и это спящий режим, проблема с 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 ]

3 голосов
/ 24 октября 2008

MySql DateTime точность только с точностью до секунды. Точность даты Java до миллисекунды. Вот почему последние три цифры являются нулями после того, как они были внесены в базу данных.

Сделайте это с вашей первоначальной датой:

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

Это установит последнюю точную секунду, и тогда все ваши сравнения будут совпадать.

(кстати, System.out.println (fromDBClock.toString ()); должно быть System.out.println (fromDBClock.date.toString ());

2 голосов
/ 23 октября 2008

SQL Server хранит дату и время с точностью до 3 миллисекунд, что определенно может вызвать проблему, с которой вы столкнулись. Одним из последствий этого является то, что 23: 59: 59.999 в Java заканчиваются тем, что на следующий день в SQL Server. У меня никогда не было проблем с Oracle, Informix или MySQL, но другие базы данных также могут иметь меньшую точность. Вы можете обойти это, используя пользовательские типы Hibernate. Вы должны округлить до чего-то менее точного, чем базовая точность базы данных, когда вы записываете значения даты. Ищите UserType в документации Hibernate, вы будете изменять метод nullSafeSet для округления.

1 голос
/ 23 октября 2008

Видимо, тип TIMESTAMP в вашей целевой РСУБД ( что вы используете, кстати? ) не хранит миллисекунды. Попробуйте найти другой собственный тип, который это делает, или сопоставьте свое время с чем-то другим, например long = ms-since-epoch.

0 голосов
/ 28 октября 2008

Personnaly, я обрезаю каждую дату, которую получаю в своем объекте POJO, с помощью класса пакетов Apache commons lang DateUtils.

См. [Сайт Apache Commons] [1]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...