2014-02-08 3 views
1

의 공통 집합을 가진 모든 기사를 찾기 I가 다음 엔터티 :JPA : 태그

@Entity 
public class Article{ 
    @Id 
    private String id; 

    @ManyToMany(cascade = CascadeType.PERSIST) 
    private Set<Tag> tags; 

//non-relevant code 
} 

@Entity 
public class Tag{ 
    @Id 
    private String id; 

    @Basic 
    @Column(nullable = false, unique = true, length = 32) 
    private String name; 

//non-relevant code 
} 

가 어떻게 효율적으로 태그의 공통 set있는 모든 Article 엔티티를 찾을 수 있습니까?

순진한 접근 방식은 각 tag에 속하는 모든 기사를 찾은 다음 모든 기사 세트 중 intersection을 반환하는 것입니다. 뭔가 같이 :

public Set<Article> findByTags(Set<Tag> tags){ 
    Set<Article> result = new HashSet<>(); 

    if(tags.isEmpty()){ 
     return result; 
    } 

    Iterator<Tag> i = tags.iterator(); 
    result.addAll(i.next().getArticles()); 

    while(i.hasNext() && !result.isEmpty()){ 
     result.retainAll(i.next()); 
    } 

    return result; 
} 

내 질문 이처럼, 아마도 DB의 모든 기사를 가져 오기 위해 필요로하지 않는이 일을 더 효율적으로, 거기에 "입니다 아마 JPQL 쿼리를 통해? 또는 CriteriaBuilder이 기본적으로 태그를 허용 세트 태그입니다 기사의 태그를 계산하고 같은 태그의 수가에 eaqual 경우

답변

5
select a from Article a where :numberOfTags = 
    (select count(distinct tag.id) from Article a2 
    inner join a2.tags tag 
    where tag in :tags 
    and a = a2) 

"(나는 그것을 전에 사용한 적이)를 사용하여 허용 된 태그 세트의 크기 (모든 태그 세트의 태그는 기사의 태그 임), 기사를 반환합니다.