0

I'm trying to return a JodaTime DateTime object. It works for the effective_date field below. But I'm not sure how to get it to return DateTime for the Event object. Any ideas?

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
}

EDIT:

I've already added Joda DateTime to the ExtendedType. The issue above only occur when I use SQLResult to build the Event object.

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

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

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

It works well when not using SQLResult to instanciate the Event object. Here, Cayenne Modeler generated the _Event class with the DateTime return type.

public abstract class _Event extends CayenneDataObject {

  <snip>

  public void setStart(DateTime start) {
    writeProperty("start", start);
  }
  public DateTime getStart() {
    return (DateTime)readProperty("start");
  }
Tuan
  • 1,476
  • 13
  • 23

1 Answers1

2

I've managed to do the following. I've created DbEntity field with OTHER as DB Type and ObjEntity field with org.joda.time.DateTime as Java Type. And it works great for your example.

Also you can try to use any third-party (or your own) ExtendedType for JodaTime DateTime.

UPDATE 1:

Also if you want to use #result directive, you need to use it for each column in your SQL template.

UPDATE 2:

Here is an example which works fine. Note that I use 4.0.M3-SNAPSHOT version with cayenne-joda module from 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());
    }

Where _Joda.class has:

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

Result:

class org.joda.time.DateTime
  • Savva, thanks for looking into this. But I've edited my question with more info. ExtendedType for DateTime is working well when I instantiate the Event object another way. It's only when I'm using SQLTemplate to query and SQLResult to instantiate the Event object, that it returns a Date object instead of Joda's DateTime – Tuan Apr 23 '15 at 20:48
  • 1
    Hi, Tuan! I've investigated your question and I haven't got the same issue. I use the newest Cayenne version from [github](https://github.com/apache/cayenne), but I think it also works for the latest release version [4.0.M2](https://cayenne.apache.org/download.html). Which version do you use? However, I've found other issue and created [JIRA ticket](https://issues.apache.org/jira/browse/CAY-2006) for it. – Sava Kalbachou Apr 25 '15 at 11:18
  • Hi Savva, I'm using 3.1. I think the issue on your JIRA ticket is similar to what I found, except I'm having with `data[0]` casting back to `Joda.class` and then try to get its DATETIME_PROPERTY. I'll see if updating to the latest version resolves this. Thanks. – Tuan Apr 27 '15 at 18:03
  • I've found that I didn't use SQLTemplate and #result directive correctly. You need to wrap all your columns to #result directive in SQL template. Also I've closed [JIRA ticket](https://issues.apache.org/jira/browse/CAY-2006) and provided comment with working examples for my use-case. I hope this will help you. – Sava Kalbachou Apr 30 '15 at 13:58
  • Hi Savva, can you test by returning a custom class in your EntityResult? For example: `EntityResult myClassResult = new EntityResult(MyClass.class);` where myClassResult has a method that returns a Joda DateTime? – Tuan Jun 11 '15 at 18:04
  • In my question above, the data object returned was an Event object. When I call `event.getStart()`, which should be returning a DateTime object, it returns a Date object instead. – Tuan Jun 11 '15 at 18:13
  • Hi Tuan. It works correctly and a method returns a Joda DateTime. I've edited my answer and provided some code. Hope it will help you. – Sava Kalbachou Jun 15 '15 at 10:34
  • Thanks for the example Savva. – Tuan Jun 24 '15 at 00:21