2010-06-22

Typesafe queries for DataNucleus

The guys from DataNucleus are now working actively on getting typesafe queries working natively in the Access Platform and later as part of the JDO standard.

The following blog post shows the direction and gives a concrete query example :

QCustomer customer = QCustomer.customer;
Query<Customer> q = pm.newTypesafeQuery(customer);
Customer bob = q.filter(customer.firstName.eq("Bob"))
     .unique(true).execute();

What about queries which return customer.firstName results?

Using the type parameter in the query there are the options of encoding the source type or the projection in the query.

The example is a bit vague, but could be transformed into the following forms

Projection as argument

QCustomer customer = QCustomer.customer;
Query q = pm.newTypesafeQuery(customer);
Customer bob = q.filter(customer.firstName.eq("Bob"))
     .unique(true).execute(customer);

What about list typed results? Do we get this type-safe?

Unique flag implicit via projection method

QCustomer customer = QCustomer.customer;
Query q = pm.newTypesafeQuery(customer);
Customer bob = q.filter(customer.firstName.eq("Bob"))
     .unique(customer);

The last example is closest to the Querydsl projection usage, and is also the most compact.

These examples manage without a type parameter, since the projection type is given in the end.

6 comments:

  1. > What about queries which return customer.firstName results?

    Obviously the user could set the type parameter of the query as that of the result class. The disadvantage of that is that the user needs to know it at the point of creating the query, though likely they ought to know at that point anyway. The advantage of setting it in execute() (your next option) is that you can reuse a query and change the result and also result class. So option 2 likely would be better for that reason alone.

    Not sure Option 3 (no explicit execute()) would get many votes, from a backwards compatibility point-of-view never mind anything else.

    ReplyDelete
  2. "unique" is just an example. The point is that you need different methods for multiple row and single row results. Otherwise it is not type-safe.

    ReplyDelete
  3. Timo,
    how does QueryDSL allows parameters/variables to be used in queries ? You have a "Param" class, but how do I get hold of one of those to use it in a query e.g as part of a filter ? Got an example URL ? Same goes for variables in JDO (does QueryDSL support them currently?). Thx

    ReplyDelete
  4. I am currently on vacation, so I keep the response brief.

    Parameters are supported via the Param class, both unnamed and named parameters are supported.

    Querydsl JDO has only query sources, the first becomes the actual source and the others act as variables.

    I will provider pointers etc after my holidays.

    ReplyDelete
  5. Thx Timo. I worked out how you currently handle params/vars. With any standardised interface we'd likely go via a factory API, with newVariable(), newParameter() methods.

    ReplyDelete
  6. Andy, here is a discussion related to Parameter usage : Query parameters

    > With any standardised interface we'd likely go via a factory API, with newVariable(), newParameter() methods.

    Let's see some further examples as code. The standalone expression model of Querydsl has many benefits, for example the default variables.

    But I guess getting queries, parameters and root variables from a factory is still acceptable.

    ReplyDelete