2012-05-22 4 views
5

używam WZP i mam następujące jednostki:Jak kwerendy dla podmiotów przez ich wartości zbiórki

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

Co chcę zrobić, to dostać zestaw FavoritesFolder podmiotów, które zawiera ciąg „ulubiony -id "w swoim zestawie elementów productsIds.

Czy ktoś wie, jak to zrobić w kryteriów api?

Aktualizacja:
myślę następujące sql powinno załatwić sprawę, ale nie jestem pewien, jak to zrobić w dowolnym JPQL lub Criteria API:

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

Odpowiedz

8

Aby otrzymać zestaw FavoritesFolder podmioty, które zawierają ciąg "ulubiony identyfikator" w swoich produktachZestaw członka z użyciem kryteriów api, należy wykonać następujące czynności:

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

Więcej informacji o n Collections in JPQL and Criteria Queries.

+1

wiem w tym temacie jesteśmy nawiązujący do identyfikatorów i dlatego muszą być równe, aby dopasować, ale powiedzmy, że mamy 'Collection ' zamiast, czy możemy zrobić zasadniczo to samo, ale zamiast potrzebować elementu, który ma być "równy", możemy mieć pozycję MATCH używając 'LIKE'? – dominicbri7

+3

@ dominicbri7 na pokrewnym [pytanie] (http://stackoverflow.com/questions/7066122/how-to-make-a-like-query-to-elementcollection-of-type-map?rq=1) Znalazłem rozwiązanie. Użyj metody łączenia w klasie Root "cb.like (from.join (" apples "). Get (" color "), textParameter) – cirovladimir

1

tylko inny sposób przy użyciu IN

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


(...) 
} 

Następnie można napisać zapytanie Criteria jak

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