2012-01-18 4 views
1

해당 필드의 목록을 포함하는 개체가 있고 해당 개체는 db에 매핑됩니다. 개체 및 앞에서 언급 한 목록에서 몇 가지 필드를 선택하는 쿼리를 만들려고합니다.JPA에서 개체의 목록 선택

개체 매핑 :

@Entity 
@Table(name="buys") 
@PrimaryKeyJoinColumn(name="buy_id") 
public class Buy extends DomainObject implements Serializable { 

     @Column(name = "buy_name") 
     private String buyName; 

     @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
     @JoinColumn(name="buy_id", referencedColumnName = "buy_id") 
     private List<InsersionOrder> insertionOrders; 

     //other fields omitted 

} 

내가 사용하고 쿼리 :

Hibernate: select buy0_.buy_id as col_0_0_, buy0_.buy_name as col_1_0_, . as col_2_0_ from buys buy0_ inner join domain_objects buy0_1_ on buy0_.buy_id=buy0_1_.id inner join insertion_orders insertiono1_ on buy0_.buy_id=insertiono1_.buy_id inner join domain_objects insertiono1_1_ on insertiono1_.io_id=insertiono1_1_.id where buy0_.buy_group_id=? and buy0_1_.is_deleted=0 

:

"select new com.dtos.domainObjects.BuyDTO(b.id, b.buyName, b.insertionOrders) from Buy b where b.buyGroupId = :groupId and b.isDeleted = false" 

이 쿼리가 최대 절전 모드 실행 (내 JPA 공급 업체가) 잘못된 쿼리를 생성 InsertionOrder 필드도 DomainObject에서 상속됩니다.

목록을 생략하고 Buy 개체 (예 : ID, 이름)에서 '간단한'입력란 만 선택하면 쿼리가 올바르게 작동합니다.

무엇이 누락 되었습니까?

감사합니다.

답변

3

이 구문은 결과 집합의 각 행에서 BuyDTO 인스턴스를 만듭니다. 그것이 효과가 있었다고하더라도, 당신이 원하는 것을 반환하지 않을 것입니다. 컬렉션 필드는 HQL 쿼리의 select 절의 일부가 될 수 없습니다.

첫 번째 해결 방법 : DTO를 반환하지 말고 엔티티 자체를 반환하십시오.

두 번째 해결 방법 : 개체를 선택하고 DTO 인스턴스를 직접 구축 :

select b from Buy b 
left join fetch b.insertionOrders i 
where b.buyGroupId = :groupId and b.isDeleted = false 

for (Buy b : list) { 
    dtoList.add(new BuyDTO(b.getId(), b.getBuyName(), b.getInsertionOrders()); 
} 

세 번째 솔루션 : 당신이 원하는 것을 선택하고, DTO들에게 자신을 조립 :

select b.id, b.buyName, i 
from Buy b 
left join b.insertionOrders i 
where b.buyGroupId = :groupId and b.isDeleted = false 

를 각 행에서 그 결과 하나의 ID, 하나의 buyName 및 하나의 insertionOrder를 찾을 수 있습니다. 따라서 새 ID를 처음 만날 때 하나의 DTO를 만들어야하며, 이미 구성된 DTO에 순서를 추가 한 다음이 ID를 충족 시키면됩니다.

+0

컬렉션이 select 절의 일부가 될 수없는 이유는 무엇입니까? 당신의 3 번째 예제에서 컬렉션 –

+1

을 선택했다는 것을 알았습니다. 많은 이해가되지 않을 것이고 Hibernate는 결과 집합의 어떤 행이 같은 목록의 일부로 그룹화되어야 하는지를 알 것입니다. HQL에 대한 참조를 찾지 못했지만 JPA2 스펙에 다음과 같이 나와 있습니다 : "SELECT 절은 단일 값 식만 반환하도록 지정해야합니다. 따라서 쿼리는 유효하지 않습니다. SELECT o .lineItems FROM Order AS "* –

+0

>'Hibernate는 결과 집합의 어떤 행을 같은 목록의 일부로 그룹화해야하는지 안다. '- 나는 그렇게 확신하지 못한다. Hibernate가 각 엔티티의 ID에 합류하기에 충분히 똑똑하다면, 전체 결과 세트를 개별 목록으로 그룹화하는 방법을 알아야합니다. 결국 이것은 수동 코드가 수행하는 것입니다. –