1

私はstackoverflowで多くのことを検索しましたが、Java.util.DateをSQLデータベースにマッピングすると問題が発生することが多く、考えられる解決策は次のとおりであることがわかりました

  • 独自の (jodatime を使用) hibernate UserType を作成する
  • データベースに永続化する前に java.util.Date を切り捨てます (精度が失われます)

ただし、私が見たすべてのケースで、日付が保存されると、最後のフィールド (ミリ秒など) が失われる (000 など) という問題がありました。私の場合は少し異なります。次のコードを検討してください。

public class TestDateTime implements Serializable {
    private long id;
    private Date created;
    private Calendar published;

    public TestDateTime(Date created, Date published) {
        this.created = created;
        this.published = GregorianCalendar.getInstance();
        this.published.setTime(published);
    }
}

<class name="TestDateTime" table="TestDateTime">
    <id name="id" type="long" column="id">
        <generator class="identity" />
    </id>
    <property name="created" column="created"/>
    <property name="published" column="published"/>
</class>

private void testSaveDate(HibernateTemplate hibernateTemplate) {
    long time = 1357747095488l;

    TestDateTime tdt = new TestDateTime(new Date(time), new Date(time));

    System.out.println("Before saving created:" + tdt.getCreated().getTime() + " (" + tdt.getCreated() + ")"
        + ", published:" + tdt.getPublished().getTime().getTime() + " (" + tdt.getPublished().getTime() + ")");
    Serializable id = hibernateTemplate.save(tdt);

    TestDateTime saved = hibernateTemplate.get(TestDateTime.class, id);

    System.out.println("After saving created:" + saved.getCreated().getTime() + " (" + saved.getCreated() + ")"
        + ", published:" + saved.getPublished().getTime() + " (" + saved.getPublished() + ")");
}

コンソールに次の出力が表示されます。

[INFO] Before saving created:1357747095488 (Wed Jan 09 16:58:15 CET 2013), published:1357747095488 (Wed Jan 09 16:58:15 CET 2013)
[INFO] Hibernate: insert into TestDateTime (created, published) values (?, ?)
[INFO] Hibernate: select testdateti0_.id as id42_0_, testdateti0_.created as created42_0_, testdateti0_.published as published42_0_ from TestDateTime testdateti0_ where testdateti0_.id=?
[INFO] After saving created:1357747095487 (2013-01-09 16:58:15.487), published:Wed Jan 09 16:58:15 CET 2013 (java.util.GregorianCalendar[time=1357747095487,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Berlin",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone[id=Europe/Berlin,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2013,MONTH=0,WEEK_OF_YEAR=2,WEEK_OF_MONTH=2,DAY_OF_MONTH=9,DAY_OF_YEAR=9,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=58,SECOND=15,MILLISECOND=487,ZONE_OFFSET=3600000,DST_OFFSET=0])

そのため、日付を SQL サーバーに保存した後、1ms を 1357747095488 から1357747095487変更します。これは、SQL Server の datetime 型の予想される動作ですか?

さらに、Date オブジェクトはチェックイン中に JackRabbit によって作成されるため、JackRabbit でこの日付を切り捨てて、SQL Server に保存されている値と同期させることはできません。

問題は、私のアプリケーションでは、この日付を比較する必要があることです。一部は JackRabbit からのもので、一部はデータベース (元は jackrabbit によって作成されたもの) からのものです。SQL Server の日付のバージョンが JackRabbit の日付と異なるため、正しく比較できません。

私にとって最善の解決策は何でしょう。つまり、マルチデータベース対応です(MySqlとMsSql 2008 R2の両方を使用しています)。long 値を自分で格納できるように、java.util.Date を bigint 列にマップする標準的な方法はありますか? または、UserType を作成する必要がありますか? クエリで long を比較できるので、これは悪い考えですか (そして、Hibernate も適切なマッピングであると想定しています)。

4

1 に答える 1

1

SQL Serverのデータ型の精度DateTimeは約 3 ミリ秒です。ここを参照してください。データ型はDateTime2より正確です。ここを参照してください。

于 2013-01-12T03:04:03.407 に答える