2012-05-22 21 views
5

Tôi đang sử dụng JPA và tôi có tổ chức sau đây:Làm thế nào để truy vấn cho các tổ chức theo giá trị bộ sưu tập của họ

@Entity 
@Table(name="favorites_folders") 
public class FavoritesFolder { 

    private static final long serialVersionUID = 1L; 

    @Id 
    private String id; 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String name; 

    @ElementCollection(fetch = FetchType.LAZY) 
    @CollectionTable(
     name="favorites_products", 
     [email protected](name="folder_id") 
     ) 
    @Column(name="product_id") 
    @NotNull 
    private Set<String> productsIds = new HashSet<String>(); 
} 

Những gì tôi muốn làm là để có được một tập hợp các thực thể FavoritesFolder nào có chứa chuỗi "yêu thích -id "trong bộ thành viên productsIds của họ.

Có ai biết làm thế nào nó có thể được thực hiện trong các tiêu chí api?

Cập nhật:
Tôi đang nghĩ đến các sql sau nên làm các trick nhưng tôi không chắc chắn làm thế nào để làm điều đó trong hai JPQL hoặc Criteria API:

select * from favorites_folders join favorites_products on favorites_folders.id = favorites_products.folder_id where favorites_products.product_id = 'favorite-id' 

Trả lời

8

Để có được một bộ FavoritesFolder các thực thể có chứa chuỗi "id yêu thích" trong sản phẩm của họ Thành viên được thiết lập bằng cách sử dụng tiêu chí api bạn nên làm như sau:

CriteriaBuilder cb = em.getCriteriaBuilder(); //em is EntityManager 
CriteriaQuery<FavoritesFolder> cq = cb.createQuery(FavoritesFolder.class); 
Root<FavoritesFolder> root = cq.from(FavoritesFolder.class); 

Expression<Collection<String>> productIds = root.get("productsIds"); 
Predicate containsFavoritedProduct = cb.isMember("favorite-id", productIds); 

cq.where(containsFavoritedProduct); 

List<FavoritesFolder> favoritesFolders = em.createQuery(cq).getResultList(); 

Thông tin thêm o n Collections in JPQL and Criteria Queries.

+1

Tôi biết trong chủ đề này, chúng tôi đang reffering để ID và do đó họ phải EQUAL để phù hợp, nhưng chúng ta hãy nói rằng chúng ta có một 'Collection ' thay vào đó, chúng ta có thể làm cơ bản cùng một điều nhưng thay vì cần một mục để được 'bằng', chúng ta có thể có một mục MATCH bằng cách sử dụng 'LIKE'? – dominicbri7

+3

@ dominicbri7 về [câu hỏi liên quan] có liên quan (http://stackoverflow.com/questions/7066122/how-to-make-a-like-query-to-elementcollection-of-type-map?rq=1) Tôi tìm thấy giải pháp. Sử dụng phương thức join trên lớp Root 'cb.like (from.join (" táo "). Get (" color "), textParameter)' – cirovladimir

1

Chỉ cần một cách khác để sử dụng trong

@Entity 
public class UserCategory implements Serializable { 
private static final long serialVersionUID = 8261676013650495854L; 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@ElementCollection 
private List<String> categoryName; 


(...) 
} 

Sau đó, bạn có thể viết một truy vấn Tiêu chuẩn như

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
    CriteriaQuery<UserCategory> q = cb.createQuery(UserCategory.class); 
    Root<UserCategory> root = q.from(UserCategory.class); 

    Predicate predicate = cb.conjunction(); 
    Predicate p1 = cb.equal(root.get(UserCategory_.targetSiteType), siteType.getName()); 
    Predicate p2 = root.get(UserCategory_.categoryName).in(category); 
    predicate = cb.and(p1,p2); 

    q.where(predicate); 

    TypedQuery<UserCategory> tq = entityManager.createQuery(q); 
    List<UserCategory> all = tq.getResultList(); 

    if (all == null || all.size() == 0){ 
     return null; 
    }else if (all.size() > 1){ 
     throw new Exception("Unexpected result - "+all.size()); 
    }else{ 
     return all.get(0); 
    } 
Các vấn đề liên quan