Wildcard.all cannot be passed to QTuple

Bug #638930 reported by Luis Fernando Planella Gonzalez
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Querydsl
Fix Released
Medium
Unassigned

Bug Description

The easiest way to retrieve a tuple with all columns of all tables would be something like:
List<Tuple> rows = query.from(a).innerJoin(a.bIdFk, b).list(new QTuple(Wildcard.all));
for (Tuple row : rows) println(row.get(a.prop1) + ", " + row.get(b.prop2));

However, there is the following error:
Exception in thread "main" java.lang.IllegalArgumentException: Got not type for [Ljava.lang.Object;
 at com.mysema.query.sql.JavaTypeMapping.getType(JavaTypeMapping.java:70)
 at com.mysema.query.sql.Configuration.getType(Configuration.java:99)
 at com.mysema.query.sql.Configuration.get(Configuration.java:69)
 at com.mysema.query.sql.AbstractSQLQuery.get(AbstractSQLQuery.java:238)
 at com.mysema.query.sql.AbstractSQLQuery.newInstance(AbstractSQLQuery.java:460)
 at com.mysema.query.sql.AbstractSQLQuery.access$300(AbstractSQLQuery.java:58)
 at com.mysema.query.sql.AbstractSQLQuery$3.produceNext(AbstractSQLQuery.java:394)
 at com.mysema.query.sql.SQLResultIterator.next(SQLResultIterator.java:73)
 at com.mysema.commons.lang.IteratorAdapter.asList(IteratorAdapter.java:40)
 at com.mysema.query.sql.AbstractSQLQuery.list(AbstractSQLQuery.java:436)
 at db.Select.main(Select.java:14)

As it is possible to use new QTuple(x.all()), which is already a multi-column projection, I think it shouldn't be too hard to support using Wildcard.all.

Tags: sql
Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

Actually it is quite hard, since Wildcard.all() provides only the wildcard symbol and not the actual paths like Q<Foo>.all(). The actual path instances are needed.

But I will try to figure out a solution.

Changed in querydsl:
importance: Undecided → Medium
Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

I don't have a solution for providing Wildcard.all() to QTuple, but I added another constructor which takes multiple Expression arrays :

    @Test
    public void test(){
        StringPath str1 = new StringPath("str1");
        StringPath str2 = new StringPath("str2");
        StringPath str3 = new StringPath("str3");
        StringPath str4 = new StringPath("str4");
        Expression<?>[] exprs1 = new Expression[]{str1, str2};
        Expression<?>[] exprs2 = new Expression[]{str3, str4};

        assertEquals(Arrays.asList(str1, str2), new QTuple(str1, str2).getArgs());
        assertEquals(Arrays.asList(str1, str2), new QTuple(exprs1).getArgs());
        assertEquals(Arrays.asList(str1, str2, str3, str4), new QTuple(exprs1, exprs2).getArgs());
    }

For example with tables Employee and Department which are joined in a query you could define the QTuple projection like this :

    new QTuple(employee.all(), department.all());

It is not perfect, but works with the FactoryExpression contract. What do you think?

The problem with Wildcard.all() is that it doesn't specify the paths of the projection. QTuple makes the mapping based on the position of the path.

Revision history for this message
Luis Fernando Planella Gonzalez (luisfpg) wrote :

Actually, it seems good enough, and was the first thing I've tried, but had to do things like adding a.all() and b.all() to a List, then converting to an array and passing to QTuple, and it didn't really fit on Querydsl's clean code :)
Thanks!

Revision history for this message
Timo Westkämper (timo-westkamper) wrote :

Released in 2.0.0-beta-1

Changed in querydsl:
status: New → Fix Committed
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.