Sql server 2008 将Hibernate日期映射到SQL Server datetime轮次为1ms

Sql server 2008 将Hibernate日期映射到SQL Server datetime轮次为1ms,sql-server-2008,hibernate-mapping,java.util.date,Sql Server 2008,Hibernate Mapping,Java.util.date,我在stackoverflow上搜索了很多,发现将java.util.Date映射到SQL数据库通常会导致问题,可能的解决方案是 创建自己的(使用jodatime)hibernate用户类型 在数据库上持久化之前截断java.util.Date(丢失精度) 然而,在我所看到的所有案例中,问题在于保存日期时,最后一个字段(例如毫秒)丢失(例如000)。在我的情况下,有点不同,考虑下面的代码: public class TestDateTime implements Serializable {

我在stackoverflow上搜索了很多,发现将java.util.Date映射到SQL数据库通常会导致问题,可能的解决方案是

  • 创建自己的(使用jodatime)hibernate用户类型
  • 在数据库上持久化之前截断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() + ")");
}
因此,在将日期保存到SQL server后,它将从1357747095488更改为1357747095487。这是SQL Server的datetime类型的预期行为吗

此外,我必须提到,日期对象是由JackRabbit在签入期间创建的,因此我不能在JackRabbit中截断此日期,以使其与存储在SQL Server中的值同步

问题是,在我的应用程序中,我必须比较这些日期,有些来自JackRabbit,有些来自数据库(最初也是由JackRabbit创建的)。由于sql server中日期的版本与JackRabbit中的版本不同,因此我无法正确比较它们


对我来说,最好的解决方案是多数据库complient(我们同时使用MySql和MsSql 2008 R2)。是否有标准方法将java.util.Date映射到bigint列,以便我自己存储长值?或者我应该创建我的用户类型?这是一个坏主意吗?因为我仍然可以比较查询中的long(我假设Hibernate也有适当的映射)

SQL Server中的
DateTime
数据类型的精度大约为3ms。看见
DateTime2
数据类型更准确。请参阅。

SQL Server中的
DateTime
数据类型的精度约为3ms。看见
DateTime2
数据类型更准确。请参阅。

如何将字段映射到datetime2列?如果我只是更改sql db中列的类型,hibernate会抱怨它需要一个“datetime”列(而不是datetime2)。@user1971430-快速搜索(hibernate映射类型datetime2)会显示各种项目。由于不熟悉Hibernate,我将冒险提出重新定义数据类型映射的建议,这可能会有所帮助。如何将字段映射到datetime2列?如果我只是更改sql db中列的类型,hibernate会抱怨它需要一个“datetime”列(而不是datetime2)。@user1971430-快速搜索(hibernate映射类型datetime2)会显示各种项目。由于不熟悉Hibernate,我将冒险提出重新定义数据类型映射的建议,这可能会有所帮助。
[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])