问题
final List<Tuple> data =
em.createQuery("SELECT p.id AS i, p.membership AS m FROM Player p WHERE p.id IN :ids", Tuple.class)
.setParameter("ids", ids)
.getResultList();
This gives the error "Cannot create TypedQuery for query with more than one return
". I could work around that by leaving out the type parameter (and using Object[] instead of Tuple, as I later found out):
@SuppressWarnings("unchecked")
final List<Object[]> data =
em.createQuery("SELECT p.id AS i, p.membership AS m FROM Player p WHERE p.id IN :ids")
.setParameter("ids", ids)
.getResultList();
But is there a solution that doesn't require unchecked code?
回答1:
A tuple isn't really any more typesafe than an array, is it?
What you could do here is use a constructor expression. Off the top of my head, this is something like:
class PlayerMembership {
public final int id;
public final MembershipType membership;
public PlayerMembership(int id, MembershipType membership) {
this.id = id;
this.membership = membership;
}
}
List<PlayerMembership> data =
em.createQuery("SELECT NEW nl.bart.PlayerMembership(p.id, p.membership) FROM Player p WHERE p.id IN :ids", PlayerMembership.class)
.setParameter("ids", ids)
.getResultList();
This requires you to write a new class to hold the result, but this will typically be pretty trivial.
回答2:
I don't think so, except using the criteria API.
But really, the type-safety and correctness of the code depends much more on the query passed to createQuery
than on the type of the list returned by the query. Moreover, you'll have to cast every element of the array anyway.
The SuppressWarnings annotation is the the last thing I would care about. The only thing that will really make the code type-safe is an automated test that executes the query and the code which consumes the result.
来源:https://stackoverflow.com/questions/8668183/nice-way-to-select-a-tuple-using-jpa