3

I have a list of columns as List<String> columns, and I would like to retrieve those columns using queryDSL.

I have this working -

   queryFactory = new JPAQueryFactory(entityManager); //where entityManager is a JPA EntityManager
   JPAQuery<?> query = queryFactory.query();
   QEmployee employee= QEmployee.employee;
   List<Tuple> result = query.select(employee.firstName, employee.lastNameemployee.lastName ,employee.age)
                .from(employee)
                .fetch();

This works fine in my test. But here I am specifying the column explicitly in the select(..) part. If my List has only firstName and age like

List<String> columnList = Arrays.asList("firstName" , "age");

then I only want to retrieve those two column from my select(..) part. QueryDSL select part only accepts Expressions, so I tried doing this:

 StringExpression[] columnListExpression =  columnList.toArray(new StringExpression[columnList.size()]) 

and then passed columnListExpression to my select(..) part as shown below,

   List<Tuple> result = query.select(columnListExpression)  // doesn't work
                .from(employee)
                .fetch();

however I get a Unsupported Operation Exception. I wanted to use queryDSL because that way I can easily construct the Predicate at runtime in a type safe manner. This SO question brushes the topic, but it was 5 years ago and now we have QueryDSL 5.0 How do I select only those columns that are present my List using queryDSL?

Something like this worked:

PathBuilder<Employee> entityPath = new PathBuilder<>( Employee  .class, "entity");
List<com.querydsl.core.Tuple> employeeResults = query.select(
entityPath.get(" firstName  ", String.class)
,entityPath.get("age", Integer.class))
.from(entityPath)
.fetch();

However, I don't know the columns before hand and need to construct this select(..) part dynamically.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
user2441441
  • 1,237
  • 4
  • 24
  • 45
  • hi, you can send column data type alongside with column name, then you can use entityPath.get – rgaraisayev Sep 28 '22 at 11:02
  • If `entityPath.get("firstName", String.class)` is valid and working, you can loop through the collection and fetch the field class via reflection. Something like `for (String field : columnList) { selectList.add(entityPath.get(field, Employee.class.getDeclaredField(field).getType())); } query.select(selectList.toArray(new PathBuilder[] {})).from(entityPath).fetch();` – XtremeBaumer Sep 29 '22 at 14:41

0 Answers0