Как получить объект JodaTime DateTime из SQLTemplate с помощью SQLResult

Я пытаюсь вернуть объект JodaTime DateTime. Это работает для поля Effective_date ниже. Но я не уверен, как заставить его возвращать DateTime для объекта Event. Любые идеи?

String sql = "SELECT a.availability_id, a.event_id, a.availability_set_id, " 
    + "e.event_id, "
    + "#result('e.start' 'org.joda.time.DateTime' '' 'event.start'), "
    + "#result('e.end' 'org.joda.time.DateTime' '' 'event.end'), "
    + "e.recurrence_id, "
    + "e.sequence, "
    + "e.uid, "
    + "#result('effective_date' 'org.joda.time.DateTime' '' 'effective_date'), " 
    + "#result('next_effective_date' 'org.joda.time.DateTime' '' 'next_effective_date') "

<snip>

EntityResult eventResult = new EntityResult(Event.class);
eventResult.addDbField(Event.EVENT_ID_PK_COLUMN, "event_id");
eventResult.addObjectField(Event.START_PROPERTY, "start");
eventResult.addObjectField(Event.END_PROPERTY, "end")

<snip>

SQLResult resultDescriptor = new SQLResult();
resultDescriptor.addEntityResult(availabilityResult);
resultDescriptor.addEntityResult(eventResult);

<snip>
List<Object[]> dataList = context.performQuery(query);
for (Object[] data : dataList) {
  Event event = (Event) data[1];
  event.getStart(); // Runs into class cast error where it's returning Date instead of DateTime
}

РЕДАКТИРОВАТЬ:

Я уже добавил Joda DateTime в ExtendedType. Вышеупомянутая проблема возникает только тогда, когда я использую SQLResult для создания объекта Event.

  // create custom ExtendedType instance
  ExtendedType dateTimeType = new DateTimeType();

  DataNode node = domain.getNode("MySQLNode");

  // install ExtendedType
  node.getAdapter().getExtendedTypes().registerType(dateTimeType);

Он хорошо работает, когда не используется SQLResult для создания экземпляра объекта Event. Здесь Cayenne Modeler сгенерировал класс _Event с возвращаемым типом DateTime.

public abstract class _Event extends CayenneDataObject {

  <snip>

  public void setStart(DateTime start) {
    writeProperty("start", start);
  }
  public DateTime getStart() {
    return (DateTime)readProperty("start");
  }

person Tuan    schedule 20.04.2015    source источник


Ответы (1)


Мне удалось сделать следующее. Я создал поле DbEntity с OTHER в качестве типа БД и поле ObjEntity с org.joda.time.DateTime в качестве типа Java. И это прекрасно работает для вашего примера.

Также вы можете попробовать использовать любой сторонний (или свой) ExtendedType для JodaTime DateTime.

ОБНОВЛЕНИЕ 1:

Также, если вы хотите использовать директиву #result, вам нужно использовать ее для каждого столбца в вашем шаблоне SQL.

ОБНОВЛЕНИЕ 2:

Вот пример, который отлично работает. Обратите внимание, что я использую версию 4.0.M3-SNAPSHOT с модулем cayenne-joda из github.

    // add CayenneJodaModule to the ServerRuntime
    ServerRuntime cayenneRuntime = new ServerRuntime(
            "cayenne-project.xml", new CayenneJodaModule());
    ObjectContext context = cayenneRuntime.newContext();

    // add Joda object
    Joda newJoda = context.newObject(Joda.class);
    newJoda.setDatetime(new DateTime());
    context.commitChanges();

    String sql = "SELECT #result('j.ID' 'int' 'ID'), "
            + "#result('j.DATETIME' 'org.joda.time.DateTime' 'DATETIME') "
            + "FROM JODA j";

    EntityResult jodaResult = new EntityResult(Joda.class);
    jodaResult.addDbField(Joda.ID_PK_COLUMN, "ID");
    jodaResult.addObjectField(Joda.DATETIME_PROPERTY, "DATETIME");

    SQLResult resultDescriptor = new SQLResult();
    resultDescriptor.addEntityResult(jodaResult);

    SQLTemplate query = new SQLTemplate(Joda.class, sql);
    query.setResult(resultDescriptor);

    List<Joda> jodaList = context.performQuery(query);
    for (Joda joda : jodaList) {
        System.out.println(joda.getDatetime().getClass());
    }

Где _Joda.class имеет:

    public void setDatetime(DateTime datetime) {
        writeProperty("datetime", datetime);
    }
    public DateTime getDatetime() {
        return (DateTime)readProperty("datetime");
    }

Результат:

class org.joda.time.DateTime
person Sava Kalbachou    schedule 23.04.2015
comment
Савва, спасибо за внимание. Но я отредактировал свой вопрос с дополнительной информацией. ExtendedType для DateTime работает хорошо, когда я создаю экземпляр объекта Event другим способом. Только когда я использую SQLTemplate для запроса и SQLResult для создания экземпляра объекта Event, он возвращает объект Date вместо DateTime Joda. - person Tuan; 23.04.2015
comment
Привет, Туан! Я изучил ваш вопрос, и у меня нет такой же проблемы. Я использую новейшую версию Cayenne из github, но я думаю, что она также работает для последней версии выпуска 4.0.M2. Какую версию вы используете? Однако я обнаружил другую проблему и создал для нее билет JIRA. - person Sava Kalbachou; 25.04.2015
comment
Привет Савва, я использую 3.1. Я думаю, что проблема с вашим билетом JIRA аналогична той, что я нашел, за исключением того, что у меня data[0] возвращается к Joda.class, а затем я пытаюсь получить его DATETIME_PROPERTY. Я посмотрю, решит ли это обновление до последней версии. Спасибо. - person Tuan; 27.04.2015
comment
Я обнаружил, что неправильно использовал SQLTemplate и директиву #result. Вам нужно обернуть все ваши столбцы директивой #result в шаблоне SQL. Также я закрыл тикет JIRA и предоставил комментарий с рабочими примерами для моего использования. -кейс. Я надеюсь, что это поможет вам. - person Sava Kalbachou; 30.04.2015
comment
Привет, Савва, можешь протестировать, вернув пользовательский класс в свой EntityResult? Например: EntityResult myClassResult = new EntityResult(MyClass.class); где у myClassResult есть метод, возвращающий Joda DateTime? - person Tuan; 11.06.2015
comment
В моем вопросе выше возвращенный объект данных был объектом Event. Когда я вызываю event.getStart(), который должен возвращать объект DateTime, вместо этого он возвращает объект Date. - person Tuan; 11.06.2015
comment
Привет Туан. Он работает правильно, и метод возвращает Joda DateTime. Я отредактировал свой ответ и предоставил код. Надеюсь, это поможет вам. - person Sava Kalbachou; 15.06.2015
comment
Спасибо за пример Савва. - person Tuan; 24.06.2015