cayenne-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrey Razumovsky <>
Subject Re: Type-safe qualifiers
Date Thu, 31 Dec 2009 09:24:53 GMT
Type-safing for expressions is cool, but I have few questions about its
Just a couple examples.

1. Instead of:
Expression clause2 = ExpressionFactory.matchExp(Artist.PAINTINGS_PROPERTY +
"." + Painting.NAME_PROPERTY, "Y");
I prefer using just
Expression clause2 = ExpressionFactory.matchExp("paintings.paintingName",
Yes, I don't like using constants, to me bottom example seems more readable,
short and quicker to write (especially if there are a lot of items in the
path). As far as I understood, this will not be allowed in new API (?)

2. I wrote a library which automatically builds Cayenne expressions from
values user specified in grid filter of Web (GWT) client - path is coming
from client. With new API, shall I have something like
CayenneDataObject.getKey(String) method to obtain any key in uniform way?
(even with that, I will have more work to do to convert path to new API,
maybe we need some method like Key Cayenne.getNestedKey(Class clazz, String

3. I have examples of intentionally not following type-safing for
expressions (these are real examples)

  a. EF.matchExp("artist", "200") - quick comparison of relation object's id
  b. EF.lessExp("date", "2010-01-01 10:00:00.000") - replacement of date (or
int, double, whatever) with just string

Will those be allowed somehow in new API?

Happy New Year!!!

2009/12/30 Andrus Adamchik <>

> While there's lots of things we need to figure out to create generified
> queries, here is one low-hanging fruit - type-safe qualifiers. The idea is
> borrowed from the WebObjects EOF extensions framework called Wonder:
> The way it works, is that for each String property in a Persistent object,
> we generate an extra parameterized "key". E.g.:
> public class _Artist extends CayenneDataObject {
>        public static final String DATE_OF_BIRTH_PROPERTY = "dateOfBirth";
>        public static final Key<Date> DATE_OF_BIRTH = new Key<Date>(
>                        DATE_OF_BIRTH_PROPERTY);
>        public static final String NAME_PROPERTY = "name";
>        public static final Key<String> NAME = new
> Key<String>(NAME_PROPERTY);
>        public static final String PAINTINGS_PROPERTY = "paintings";
>        public static final Key<Painting> PAINTINGS = new Key<Painting>(
>                        PAINTINGS_PROPERTY);
> ...
> Key class is a builder of type-safe key-value expressions (see the link
> above for the type of methods that it has). I wrote a quick API-only
> prototype that is a replacement of ExpressionFactory. Here is an example of
> building the following Expression the old way and the new way:
>  Expression: name='X' and ('Y' or'Z' or
> 1. Current API:
> Expression clause1 = ExpressionFactory.matchExp(Artist.NAME_PROPERTY, "X");
> Expression clause2 = ExpressionFactory.matchExp(Artist.PAINTINGS_PROPERTY +
> "." + Painting.NAME_PROPERTY, "Y");
> Expression clause3 = ExpressionFactory.matchExp(Artist.PAINTINGS_PROPERTY +
> "." + Painting.NAME_PROPERTY, "Z");
> Expression clause4 = ExpressionFactory.matchExp(Artist.PAINTINGS_PROPERTY +
> "." + Painting.NAME_PROPERTY, "A");
> Expression clause23 = clause2.orExp(clause3);
> Expression clause234 = clause23.orExp(clause4);
> Expression qualifier = clause1.andExp(clause234);
> 2. New API:
> Expression clause1 = Artist.NAME.eq("X");
> Expression clause2 ="Y");
> Expression clause3 ="Z");
> Expression clause4 ="A");
> Expression qualifier = Each.get(clause1, Any.get(clause2, clause3,
> clause4));
> As you see the new API is much tighter, and the first part of it is
> completely type-safe (generated "keys" ensure that we are matching against
> the right type of value, even in a multi-step path). The last line uses 2
> new Expression factories, "Each" and "Any", to quickly organize key-value
> expressions into a nested expression tree. I think this is as good as it can
> get within the constraints of the Java syntax.
> I'd like to see if a similar approach can be extended to query building.
> Although that'll be a entirely different level of effort. For one thing it
> may force us to reconcile EJQBL and SelectQuery into a single query
> (SelectQuery is functionally a subset of EJBQLQuery. But SelectQuery
> "compilation" into SQL is fairly optimized, while EJBQLQuery-to-SQL
> conversion involves a much longer and slower pipeline). Plus of course there
> are other obstacles that we discussed before (such as a variety of possible
> result types).
> Andrus


  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message