2011-12-29 2 views
4
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(); 

이렇게하면 "Cannot create TypedQuery for query with more than one return"오류가 발생합니다. 나는 (내가 나중에 발견하고, 객체 [] 대신 튜플의 사용) 형식 매개 변수를 두어 그 해결 수 :JPA를 사용하여 튜플을 선택하는 좋은 방법

@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(); 

을하지만 선택하지 않은 코드를 필요로하지 않는 솔루션이있다?

답변

10

튜플은 배열보다 더 형식 안전하지 않습니다. 그렇습니까?

여기서 할 수있는 것은 생성자 표현식을 사용하는 것입니다.

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(); 

이 결과를 저장하는 새로운 클래스를 작성하도록 요구하지만,이 일반적으로 아주 사소한 것 : 내 머리 위로 떨어져,이 같은 것입니다.

+0

이것은 내가 어디에서 찾았는지 기억이 나지 않지만, 내가 한 일이다. –

4

기준 API를 사용하는 경우를 제외하고는 그렇게 생각하지 않습니다.

실제로 코드의 형식 안전성과 정확성은 쿼리에서 반환 한 목록의 유형보다 createQuery에 전달 된 쿼리에 훨씬 더 의존합니다. 또한 어쨌든 배열의 모든 요소를 ​​캐스팅해야합니다.

SuppressWarnings 주석은 내가 신경 써야 할 마지막 사항입니다. 실제로 코드 유형을 안전하게 만드는 유일한 것은 쿼리와 결과를 사용하는 코드를 실행하는 자동화 된 테스트입니다.

+1

+1 튜플의 "유형 안전성"은 Criteria API 자체에서 비롯됩니다. –

관련 문제