2013-12-05 28 views
5

Làm cách nào để tạo truy vấn Tiêu chí JPA hiệu quả để chọn danh sách các thực thể chỉ khi chúng tồn tại trong bảng tham gia? Ví dụ lấy ba bảng sau:Truy vấn Tiêu chí JPA trên 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 

Các truy vấn trong câu hỏi (những gì tôi muốn JPA để sản xuất) là:

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

Truy vấn Tiêu chuẩn sau đây sẽ tạo ra một kết quả tương tự, nhưng với hai tham gia :

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

các vấn đề cơ bản dường như là tôi đang sử dụng chú thích @JoinTable cho USER_WORKGROUP tham gia bảng thay vì một @Entity riêng biệt cho các bảng tham gia nên nó dường như không Tôi có thể sử dụng USER_WORKGROUP làm Gốc trong truy vấn tiêu chí.

Dưới đây là các lớp thực thể:

@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

Bạn có thể cho chúng tôi thấy các lớp '@ Entity' của bạn không? –

+0

@Templar - Các lớp thực thể được thêm vào. – Ryan

Trả lời

0

Theo như tôi biết, JPA về cơ bản bỏ qua các bảng tham gia. Các JPQL mà bạn làm sẽ là

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

cho truy vấn Tiêu chuẩn, bạn sẽ có thể làm:

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

không cần phải lo lắng về giữa bảng tham gia.

Các vấn đề liên quan