Правильное использование org.joda.time.contrib.hibernate.PersistentDateTime с webapp, настроенным для другого часового пояса, чем db - PullRequest
0 голосов
/ 15 сентября 2011

Я уверен, что это встречалось много раз и написано где-то еще.Заранее извиняюсь за многословный пост, но я хотел предоставить как можно больше подробностей.

У меня есть рабочая станция, на которой JVM работает в одном часовом поясе (в моем случае -07: 00).У меня есть база данных Oracle, настроенная на сохранение значений даты в UTC.

Я пытаюсь использовать расширение jodatime, http://www.joda.org/joda-time-hibernate/,, которое имеет настраиваемые типы 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, (выберитеto_timestamp ('2011-08-03 13:00', 'YYYY-MM-DD HH24: MI') из dual), 298384);

Запрос Hibernate в моем DAO выглядит примерно такthis

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)

для получения DateTime.

Вот пример вывода результатов тестового прогона (извините за плохое форматирование)

16: 22: 31 729 DEBUG [AbstractBatcher] собирается открыть PreparedStatement (open PreparedStatements: 0, глобально: 0)
16: 22: 31 732 DEBUG [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 =?Hibernate:
выберите
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_.BID
и (
mNid00.,?
)
)
и (
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] - Ср. 3 августа 13:00:00 PDT 2011
16: 22: 31 799 Параметр привязки TRACE [BasicBinder] [4] как [TIMESTAMP] - четверг, август 13:00:00 PDT 2011
16: 22: 31,801 Параметр привязки TRACE [BasicBinder] [5] как [VARCHAR] - D
16: 22: 31,801 Параметр привязки TRACE [BasicBinder] [6] как [ЧИСЛО] - 260699

и затем тест не пройден

Результаты:

Неудачные тесты:
testFindVirtualBids (com.spp.mui.persistence.hibernate.MktBidDAOTest): ожидается: <2> но было: <0>

Выполнено тестов: 2, сбоев: 1, ошибок: 0, пропущено: 0

Почему утверждение моего теста не пройдет?

1 Ответ

0 голосов
/ 30 сентября 2011

Я решил это сам. Сложная часть в том, как я вставлял даты. Я выбрал другой маршрут, для которого, к сожалению, я не могу поделиться кодом. Достаточно сказать, что я разработал тестовый базовый класс с подпрограммой для загрузки в CSV-файлы. Он использует Spring Test Framework, в частности аннотированный метод @BeforeTransaction, который делегирует помощникам для работы с различными типами String (например, дата, число, byte [] и т. Д.).

Форматер в корне правильный. Для тех, кому любопытно, метод timeDispatcher impl выглядит так ...

 public DateTime getDateTimeFromXMLDateTime(String xmlDateTime) {  
    if(xmlDateTime == null || "".equals(xmlDateTime)) {  
        return null;  
    } else {  
        return isoParser.parseDateTime(xmlDateTime).withZone(gmtTZ);  
    }  
}  

, где

isoParser = ISODateTimeFormat.dateTimeParser(DateTimeZone.getDefault());  

и

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