如何使用SQLResult从SQLTemplate获取JodaTime DateTime对象

时间:2015-04-20 23:30:58

标签: apache-cayenne

我正在尝试返回一个JodaTime DateTime对象。它适用于下面的effective_date字段。但我不知道如何让它为Event对象返回DateTime。有什么想法吗?

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使用DateTime返回类型生成_Event类。

public abstract class _Event extends CayenneDataObject {

  <snip>

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

1 个答案:

答案 0 :(得分:2)

我设法做了以下事情。我创建了DbEntity字段,其中OTHER为DB Type和ObjEntity字段,org.joda.time.DateTime为Java Type。 它适用于你的例子。

此外,您可以尝试使用JodaTime DateTime的任何第三方(或您自己的)ExtendedType。

更新1:

此外,如果您想使用#result指令,则需要将它用于SQL模板中的每一列。

更新2:

这是一个工作正常的例子。 请注意,我使用来自github的cayenne-joda模块的4.0.M3-SNAPSHOT版本。

    // 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