On 27/12/2007, at 1:29 AM, Mike Kienenberger wrote:
> String pathSpec = Artist.ARTIST_NAME_PROPERTY;
> or
> String pathSpec = Painting.ARTIST_PROPERTY + "." +
> Artist.ARTIST_NAME_PROPERTY;
>
> Note also, that the pastSpec has the same suffix -- all you need to do
> is adjust the prefix to account for a different root:
But that is exactly my point: the Expression object is different
depending on where the root of the query starts. Sure the end part of
the expression is the same, but that doesn't help anyone reuse an
Expression object and so it is intrinsically tied to a root entity.
Andrus's point is that they can be reused if you happen to name your
properties the same between multiple entities, but the thought hadn't
even occurred to me that this would be useful - I'd consider it poor
practice to make these sorts of assumptions about the model. Someone
could change the model and break a whole lot of code without a single
compile time exception.
Expression e = ExpressionFactory.matchExp(Painting.NAME_PROPERTY,
"bob");
Sure, the Painting.NAME_PROPERTY and Artist.NAME_PROPERTY might both
be equal("name") and the above expression will work for both artists
called bob and paintings called bob. But does anyone actually use
Cayenne like this? What happens when someone changes
Artist.NAME_PROPERTY to Artist.LASTNAME_PROPERTY?
Could it then make sense to do this:
1. Expression<Artist> e =
ExpressionFactory.matchExp(Artist.NAME_PROPERTY, "bob", Artist.class);
2. e = e.andExpr(ExpressionFactory.matchExp(Artist.SUBURB_PROPERTY,
"Newtown", Artist.class));
3. e = e.andExpr(ExpressionFactory.matchExp(Artist.STATE_PROPERTY,
"NSW")); <--- no compile time checking here
4. e = e.andExpr(ExpressionFactory.matchExp(Artist.NAME_PROPERTY,
"bob", Painting.class)); <--- oops, error here
The benefits:
* when combining expressions (eg. andExp) type safety can be enforced
at compile time (if the root class is passed for each expression which
makes up the whole)
* the root entity class can flow through to query without needing to
be passed again: simpler, cleaner API. Expression and Query get
generified together.
* works like EJBQL which people will probably get to know over time
The cons:
* can't use the trick of sharing expressions across properties with
identical names from several entities
* something makes me think that line 3 may run into problems with
generics internal to Cayenne code and we will not be able to force the
cast of <?> into <Artist>. But I remain hopeful that there is a way,
and even if not it doesn't kill the idea, just make it more awkward to
use when building long compound expressions.
* significant change to the previous API (but if we are going to force
people to make a change, better that it be done as best we can right
now)
I know this is just half the problem (the other half is how to decide
whether you are getting datarows or some other type back from a
query), so I just throw this up as an idea. To my mind it is the
philosophically appropriate place to inject the root entity.
Ari Maniatis
-------------------------->
ish
http://www.ish.com.au
Level 1, 30 Wilson Street Newtown 2042 Australia
phone +61 2 9550 5001 fax +61 2 9550 4001
GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A
This archive was generated by hypermail 2.0.0 : Thu Dec 27 2007 - 03:51:41 EST