Since there was a clear dissatisfaction with all suggested solutions, I kept trying other options. Here is one more attempt. I ditched both ideas - to subclass existing queries and to implement Query wrappers that are not queries themselves. Instead I combined functionality of the existing queries and a user-friendly wrapper in single new class that is itself a Query. As a result there's no backwards compatibility issues allowing for the tight and clean API.

1. an example of usage... Notice that DataRows/Persistent/Generic objects are all handled by the same query class:

Select<Artist> query1 = new Select<Artist>(Artist.class);
query1.andQualifier("artistName = 'ABC'")
     .orQualifier("artistName = 'XYZ'")
     .orderAscending(Artist.ARTIST_NAME_PROPERTY);
List<Artist> artists = context.performQuery(query1);

Select<DataRow> query2 = new Select<DataRow>(DataRow.class, "Artist");
query2.andQualifier("artistName = 'ABC'")
     .orQualifier("artistName = 'XYZ'")
     .orderAscending(Artist.ARTIST_NAME_PROPERTY);
List<DataRow> dataRows = context.performQuery(query2);



2. here is an implementation draft... Omitted are SQLSelect, NamedSelect, and ProcedureSelect. Also I think at the end "Select" will be based internally on EJBQLQuery, not SelectQuery, as it has a number of extra capabilities...

interface TypedQuery<T> extends Query {

}

interface ObjectContext {
  List<T> performQuery(TypedQuery<T> query);
}


public class Select<T> implements TypedQuery<T> {

        protected SelectQuery delegateQuery;

        public Select(Class<T> rootClass) {
                this.delegateQuery = new SelectQuery(rootClass);
        }

        public Select(Class<T> rootClass, String entityName) {

                if (entityName == null) {
                        this.delegateQuery = new SelectQuery(rootClass);
                } else {
                        this.delegateQuery = new SelectQuery(entityName);

                        if (rootClass.isAssignableFrom(DataRow.class)) {
                                delegateQuery.setFetchingDataRows(true);
                        }
                }
        }

        public Select<T> andQualifier(Expression qualifier) {
                delegateQuery.andQualifier(qualifier);
                return this;
        }

        public Select<T> andQualifier(String qualifier) {
                delegateQuery.andQualifier(Expression.fromString(qualifier));
                return this;
        }

        public Select<T> orQualifier(Expression qualifier) {
                delegateQuery.orQualifier(qualifier);
                return this;
        }

        public Select<T> orQualifier(String qualifier) {
                delegateQuery.orQualifier(Expression.fromString(qualifier));
                return this;
        }

        public Select<T> orderAscending(String ordering) {
                delegateQuery.addOrdering(ordering, Ordering.ASC);
                return this;
        }

        public Select<T> orderDesending(String ordering) {
                delegateQuery.addOrdering(ordering, Ordering.DESC);
                return this;
        }

       // other methods follow here...
}

3. What I haven't done yet is applying this to the new List<Object[]> results, as the backend is not fully ready yet, and I need a better understanding of all consequences myself.


So ... does the above sound acceptable, or are there still reservations?

Andrus




Reply via email to