John Rumpel
John Rumpel

Reputation: 4615

JPA: Result list - Cast Object[] to tuple

simple question, but I don't see my error in reasoning. Having a named query with selected members as result instead of the entire row/entity.

Now I want to access the member fields with the convenient tuple methods.

q = em.createNamedQuery("test.findvar");
List<Tuple> tuples = q.getResultList();    
for (Tuple t : tuples)
   System.out.println(t.get(0) + " " + t.get(1));

Unfortunately it throws me:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to javax.persistence.Tuple

All works fine with:

q = em.createNamedQuery("test.findvar");
List<Object[]> objs = q.getResultList();    
for (Object[] obj : objs)
    System.out.println(obj[0] + " " + obj[1]);

What's wrong with my first solution?

Upvotes: 1

Views: 11046

Answers (2)

Ron HD
Ron HD

Reputation: 388

With Java 8 OpenJDK 1.8.0, EJB 3.2, Payara (Glassfish) 5.183, putting Tuple.class as the second argument to createNamedQuery has no effect. It compiles fine, but the getResultList() call still returns List<Object[]>.

Also, the new getResultStream() method returns a Stream<Object[]>, with or without the Tuple.class arg.

Worse, the compiler doesn't seem to know the type of objects being streamed or used from the list (a bug IMO), so any attempt to actually use the returned query values will give compiler errors unless the value is explicitly cast.

Upvotes: 0

Dmitry Kuskov
Dmitry Kuskov

Reputation: 1021

You can specify return type in createNamedQuery(), as noted in javadoc

So your code should look like:

q = em.createNamedQuery("test.findvar", Tuple.class);
List<Tuple> tuples = q.getResultList();    
for (Tuple t : tuples)
   System.out.println(t.get(0) + " " + t.get(1));

When you specify return type, TypedQuery instance is created, instead of Query instance. Query does not use generics and returns simply java.util.List.

Upvotes: 5

Related Questions