3

I have the following Criteria API code which returns List.

I would like to convert this to List<myClass>

How can I do this?

CriteriaQuery<Tuple> cq = cb.createTupleQuery();

Root<ProductCatalogue> pc = cq.from(ProductCatalogue.class);
Root<ProductList> al = cq.from(ProductList.class);
.......
.......
.......

Predicate[] predicates = new Predicate[predicateList.size()];
predicateList.toArray(predicates);
criteriaQuery.where(predicates);

TypedQuery<Tuple> typedQuery = getEntityManager().cq(criteriaQuery);
List<Tuple> tuple = typedQuery.getResultList();

Ideally I would like to

List<Employee> emp = tuple

However the above resulted in incompatible type error, I do not know how could I cast this.

Jacob
  • 14,463
  • 65
  • 207
  • 320
  • 3
    Do you really need the Tuples? If not, why don't you create a straight `CriteriaQuery`? See [here](http://docs.oracle.com/javaee/6/tutorial/doc/gjrij.html) for instance – perissf Nov 16 '15 at 14:43

1 Answers1

4

If you insist on using a tuple query you'll have to convert the instances manually.
If myClass is an entity you should use CriteriaQuery< myClass> as perissf suggested, otherwise you may use a "constructor expression" to create instances directly from a select, for example:

select new com...myClass(c.id, c.price) FROM ProductList c WHERE c.....;

See this answer for an example to create such a query using the Criteria API.

Community
  • 1
  • 1
Robin
  • 3,226
  • 2
  • 20
  • 27
  • 1
    Reason for using Tuple is because of [this](http://stackoverflow.com/a/8770341/599528). In order to get rid of `Partial object queries are not allowed to maintain the cache or be edited` I have started using Tuple. – Jacob Nov 16 '15 at 18:29
  • I understand, you don't want to select all data required for the entity and that's why JPA can't create instances from the (partial) query. So you're using a Tuple query, fine. But how do you expect to have an automatic mapping between an arbitrary Tuple and your class? Magic? Now if you think well, I could pass some kind of mapping instruction to the query voila, this is the socalled "constructor expression" I mentioned in my answer! – Robin Nov 17 '15 at 09:23
  • 1
    _After_ the query you're in normal Java land again which means there can't possibly exist any kind of automatic mapping (cast) between Tuple and your class! But using Java8 streams your conversion may be as easy as return `tuples.stream().map(t -> new MyClass(t.get(idExpr), t.get(priceExpr), ...)).collect(Collectors.toList())` – Robin Nov 17 '15 at 09:23
  • Then use a constructor expression or a loop. And in case this wasn't clear enough: you can use a constructor expression for entities as well. – Robin Nov 17 '15 at 13:09
  • Robin, I have managed to solve the issue by Constructor Expression, thanks a lot for the insight – Jacob Nov 24 '15 at 05:22