On Dec 26, 2007, at 4:14 AM, Aristedes Maniatis wrote:
>
> On 25/12/2007, at 2:20 AM, Andrus Adamchik wrote:
>
>> - List<?> performQuery(Query query);
>> + ..uppressWarnings("unchecked")
>> + List performQuery(Query query);
>>
>
> I agree. Returning <?> from a function call does nothing for type
> safety at all, so it may as well not be there. Pretty much everwhere
> we return <?> from a function should be considered suspect and some
> of the places <Object> can be found are also candidates for
> refactoring.
Will go ahead with this change.
> On 22/12/2007, at 2:53 AM, Andrus Adamchik wrote:
>
>> The wrapper idea (SelectBuilder) is sort of along the lines of
>> reversing the API that you suggested. But let me comment on why I
>> am not a fan of adding new ways to run a query to the
>> ObjectContext. When implementing ROP and nested contexts I found
>> out that having so many "redundant" or "utility" methods in a
>> context object makes it extremely hard to implement multi-layer
>> contexts. So I'd prefer that we keep ObjectContext API as lean as
>> possible, and pass all query parameters in the query object itself.
>
> What we are discussing comes down to whether the query type
> (datarows or persistent objects) should be injected into the Query
> as part of the constructor (as per your new SelectBuilder or Tore's
> subclass idea), sometime after (as per the existing Query) or when
> you want the query executed (as per my idea with multiple return
> functions).
IMO this is a rather accurate analysis.
> List<Artists> result = query.getResult(Artist.class, context);
> Map<String, Artists> result = query.getResultAsMap(Artist.class,
> context, NAME_PROPERTY);
> List<DataRow> result = query.getResultAsDataRows(Artist.class,
> context);
Since Query interface is another core Cayenne abstraction, adding
utility methods to it is causing a similar ripple effect as adding
them to ObjectContext... E.g. a DeleteBatchQuery would now have a
'getResult' method... Also we'd have to add update methods returning
update counts, select methods returning Object[] (something we are
implementing now per JPA), etc... In other words, too many loose ends.
So, weighing all options, I think we can make a bit of a concession on
the ObjectContext expansion, to provide minimally generics-friendly
API without changing how Cayenne works, and move all utilities (such
as getResultAsMap fetch) to the new Builders:
// existing
List performQuery(Query query);
// existing
QueryResponse performGenericQuery(Query query);
// new
<T> List<T> performQuery(Class<T> aClass, Query query);
// new
List<DataRow> performDataRowQuery(Query query);
It still makes things a bit more verbose (and redundant, as Class will
be specified twice - once in query constructor, and second time in the
context), but everything about generics is verbose and redundant after
all :-/ I guess after that we can deprecate 'setDataRows' on
SelectQuery and SQLTemplate, (as well as
"ObjectContext.performQuery(Query)", although we can keep this one
around longer as it is heavily used by everybody).
Hmm... actually this would allow us to make Class argument optional in
the constructor of SelectQuery, and SQLTemplate, that most often than
not fetches DataRows anyways.
I need to do more analysis how the new JPA related result sets will
play with this... But what is everyone's feeling on that? Seems like
the least invasive change to me....
> I have to confess to not quite understanding the boundaries between
> Expression and Query. 99% of the times that it is used, a Query is
> just an Expression with Ordering and a root entity.
Yes, Expression is a qualifier *part* of the SelectQuery.
> But I don't understand why that root entity isn't part of the
> Expression itself - does an expression have much meaning without a
> root entity? It is always implied within the Expression, since you
> can't create an expression which is meaningful for Artist.class and
> then create a new SelectQuery(Painting.class).
Coincidentally, since Expressions are not bound to a java class, you
can use the same expression with a group of classes that do not
inherit from each other, but simply share property names. I think of
that as a nice side effect. The design idea is that a SelectQuery is a
composition of the parts, Expression being one of them.
Andrus
This archive was generated by hypermail 2.0.0 : Wed Dec 26 2007 - 05:50:34 EST