2013-12-05 14 views
5

Öğelerin bir listesini yalnızca bir birleştirme tablosunda varlarsa seçmek için verimli bir JPA Kriteri sorgusu nasıl oluştururum? Örneğin aşağıdaki üç tablo almak:JPA Ölçüt Tablosu JoinTable

create table user (user_id int, lastname varchar(64)); 
create table workgroup (workgroup_id int, name varchar(64)); 
create table user_workgroup (user_id int, workgroup_id int); -- Join Table 

soru (ı JPA üretmek istediğini) sorgu geçerli:

select * from user where user_id in (select user_id from user_workgroup where workgroup_id = ?); 

aşağıdaki kriterler sorgu benzer bir sonuç üretecektir, ancak iki katılır ile : o görünmüyor böylece

temel sorunu ben USER_WORKGROUP için @JoinTable ek açıklama kullanıyorum o gibi görünüyor
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); 
    CriteriaQuery<User> cq = cb.createQuery(User.class); 
    Root<User> root = cq.from(User.class); 
    cq.select(root); 

    Subquery<Long> subquery = cq.subquery(Long.class); 
    Root<User> subroot = subquery.from(User.class); 
    subquery.select(subroot.<Long>get("userId")); 
    Join<User, Workgroup> workgroupList = subroot.join("workgroupList"); 
    subquery.where(cb.equal(workgroupList.get("workgroupId"), ?)); 
    cq.where(cb.in(root.get("userId")).value(subquery)); 

    getEntityManager().createQuery(cq).getResultList(); 

yerine katılmak tablo için ayrı bir @Entity tablosunu katılmak Bir ölçüt sorgusunda USER_WORKGROUP'u Kök olarak kullanabilirim.

@Entity 
public class User { 
    @Id 
    @Column(name = "USER_ID") 
    private Long userId; 
    @Column(name = "LASTNAME") 
    private String lastname; 
    @ManyToMany(mappedBy = "userList") 
    private List<Workgroup> workgroupList; 
} 

@Entity 
public class Workgroup { 
    @Id 
    @Column(name = "WORKGROUP_ID") 
    private Long workgroupId; 
    @Column(name = "NAME") 
    private String name; 
    @JoinTable(name = "USER_WORKGROUP", joinColumns = { 
     @JoinColumn(name = "WORKGROUP_ID", referencedColumnName = "WORKGROUP_ID", nullable = false)}, inverseJoinColumns = { 
     @JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID", nullable = false)}) 
    @ManyToMany 
    private List<User> userList; 
} 
+1

Bize "Entity" sınıflarınızı gösterebilir misiniz? –

+0

@Templar - Varlık sınıfları eklendi. – Ryan

cevap

0

olarak bildiğim kadarıyla, JPA esasen katılmak tablo yok sayar:

İşte varlık sınıfları bulunmaktadır. masaya katılmak ortada endişelenecek gerek yoktur

Criteria c = session.createCriteria(User.class, "u"); 
c.createAlias("u.workgroupList", "wg"); 
c.add(Restrictions.eq("wg.name", groupName)); 
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 

var: yapmanız JPQL yapmanız gerekir, Kriter sorgusu için

select distinct u from user u join u.workgroupList wg where wg.name = :wgName 

olurdu.