【发布时间】:2011-11-17 13:52:16
【问题描述】:
我相信这已经被多次遇到过,并且在其他地方也有过报道。提前为这篇冗长的帖子道歉,但我想在前面提供尽可能多的细节。
我有一台在一个时区(在我的情况下为 -07:00)运行 JVM 的工作站。我有一个配置为以 UTC 保存日期值的 Oracle 数据库。
我正在尝试使用具有自定义 Hibernate 类型的 jodatime 扩展 http://www.joda.org/joda-time-hibernate/,其中之一是 PersistentDateTime。
这是我的 .hbm.xml 中的一个示例。
<hibernate-mapping>
<class name="com.spp.mui.domain.MktBidHourly" table="MKTBIDHOURLY">
<comment>Entity to represent the hourly participant bids</comment>
<id name="bidId" type="big_decimal">
<column name="BIDID" precision="22" scale="0" />
<generator class="foreign">
<param name="property">mktBid</param>
</generator>
</id>
<one-to-one name="mktBid" class="com.spp.mui.domain.MktAbstractBid" constrained="true"></one-to-one>
<property name="period" type="org.joda.time.contrib.hibernate.PersistentDateTime">
<column name="PERIOD" length="7">
<comment>Identifies the Period for which the bid applies.</comment>
</column>
</property>
<property name="bidCurveId" type="big_decimal">
<column name="BIDCURVEID" precision="22" scale="0">
<comment>A database-generated unique identifier for the bid curve</comment>
</column>
</property>
</class>
注意 MktBidHourly 中的期间字段。
因此,在为我的一个 DAO(使用 Spring)执行单元测试之前,我使用 Toad(用于 Oracle)之类的工具来插入一些数据,这些数据将在测试中被查询,例如
插入 MKTBIDHOURLY 值 (33, (select to_timestamp('2011-08-03 13:00', 'YYYY-MM-DD HH24:MI') 来自双), 298384);
我的 DAO 中的 Hibernate 查询看起来有点像这样
public static final String QRY_FIND_BIDS =
"from MktBid bid where bid.priceNodeId in (:priceNodeIdList) and bid.mktBidHourly.period in (:periodsList) and bid.mktBidType = (:bidType) and bid.participantId = (:participantId)";
Query q = getSession().createQuery(MktQueries.QRY_FIND_BIDS);
q.setParameterList("priceNodeIdList", priceNodeIds);
q.setParameterList("periodsList", periods);
q.setEntity("bidType", bidType);
q.setBigDecimal("participantId", participantId);
realBids = q.list();
这是测试方法
@Test
public void testFindVirtualBids() throws ParseException {
List<MktVirtualBid> candidateBids = new ArrayList<MktVirtualBid>();
MktBidType bidType = new MktBidType(MktBid.VIRTUAL_BID);
candidateBids.add(data.createMktVirtualBid(new BigDecimal(LOCATION_ID_1), false, timeDispatcher.getDateTimeFromXMLDateTime("2011-08-03T13:00:00-07:00"), new BigDecimal(CURVE_ID_1)));
candidateBids.add(data.createMktVirtualBid(new BigDecimal(LOCATION_ID_2), false, timeDispatcher.getDateTimeFromXMLDateTime("2011-08-04T13:00:00-07:00"), new BigDecimal(CURVE_ID_2)));
List<MktVirtualBid> foundBids = dao.findVirtualBids(bidType, new BigDecimal(PARTICIPANT_ID), candidateBids);
Assert.assertEquals(2, foundBids.size());
}
注意 timeDispatcher 方法正在使用
ISODateTimeFormat.dateTimeParser().withZone(DateTimeZone.getDefault())
作为格式化程序,然后
parseDateTime(xmlDateTime).withZone(DateTimeZone.UTC)
获取日期时间。
这是测试运行的一些示例输出(抱歉格式不佳)
16:22:31,729 DEBUG [AbstractBatcher] 即将打开 PreparedStatement(打开 PreparedStatements:0,全局:0)
16:22:31,732 调试 [SQL]
选择
mktbid0_.BIDID 为 BIDID5_,
mktbid0_.BIDTYPE 为 BIDTYPE5_,
mktbid0_.PARTICIPANTID 为 PARTICIP3_5_,
mktbid0_.PNODEID 为 PNODEID5_,
mktbid0_.USEBIDSLOPE 作为 USEBIDSL5_5_
来自
DEVMOI2.MKTBID mktbid0_,
DEVMOI2.MKTBIDHOURLY mktbidhour1_
在哪里
mktbid0_.BIDID=mktbidhour1_.BIDID
和 (
mktbid0_.PNODEID 在 (
? , ?
)
)
和 (
mktbidhour1_.PERIOD in (
? , ?
)
)
和 mktbid0_.BIDTYPE=?
和 mktbid0_.PARTICIPANTID=?休眠:
选择
mktbid0_.BIDID 为 BIDID5_,
mktbid0_.BIDTYPE 为 BIDTYPE5_,
mktbid0_.PARTICIPANTID 为 PARTICIP3_5_,
mktbid0_.PNODEID 为 PNODEID5_,
mktbid0_.USEBIDSLOPE 作为 USEBIDSL5_5_
来自
DEVMOI2.MKTBID mktbid0_,
DEVMOI2.MKTBIDHOURLY mktbidhour1_
在哪里
mktbid0_.BIDID=mktbidhour1_.BIDID
和 (
mktbid0_.PNODEID 在 (
? , ?
)
)
和 (
mktbidhour1_.PERIOD in (
? , ?
)
)
和 mktbid0_.BIDTYPE=?
和 mktbid0_.PARTICIPANTID=?
16:22:31,733 TRACE [AbstractBatcher] 准备声明
16:22:31,798 TRACE [BasicBinder] 绑定参数 [1] 作为 [NUMERIC] - 262235
16:22:31,798 TRACE [BasicBinder] 绑定参数 [2] 作为 [NUMERIC] - 262234
16:22:31,799 TRACE [BasicBinder] 绑定参数 [3] 作为 [TIMESTAMP] - 2011 年 8 月 3 日星期三 13:00:00 PDT
16:22:31,799 TRACE [BasicBinder] 绑定参数 [4] 作为 [TIMESTAMP] - 2011 年 8 月 4 日星期四 13:00:00 PDT
16:22:31,801 TRACE [BasicBinder] 绑定参数 [5] 作为 [VARCHAR] - D
16:22:31,801 TRACE [BasicBinder] 绑定参数 [6] 作为 [NUMERIC] - 260699
然后测试失败
结果:
失败的测试:
testFindVirtualBids(com.spp.mui.persistence.hibernate.MktBidDAOTest):预期: 但为:测试运行:2,失败:1,错误:0,跳过:0
为什么我的测试断言没有通过?
【问题讨论】:
-
我应该补充一点,当我尝试运行 Hibernate 发出的查询时,用 Toad 之类的工具替换参数值会得到结果。
标签: oracle hibernate spring timezone jodatime