2012-05-22 6 views
5

estoy usando JPA y tengo la siguiente entidad:Cómo realizar consultas a las entidades por su valor de colección

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

Lo que quiero hacer es conseguir un conjunto de entidades FavoritesFolder que contiene la cadena "favorito -id "en su conjunto de miembros productsIds.

¿Alguien sabe cómo se puede hacer en criterios api?

Actualización:
Estoy pensando en el siguiente SQL debe hacer el truco, pero no estoy seguro de cómo hacerlo, ya sea en JPQL o Criteria API:

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

Respuesta

8

para obtener un conjunto de FavoritesFolder entidades que contiene la cadena "favorito-id" en su miembro productsIds establecidos utilizando los criterios del API que debe hacer lo siguiente:

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

Más información o n Collections in JPQL and Criteria Queries.

+1

Sé que en este tema estamos según los planes de ID y por lo tanto tiene que ser igual a la altura, pero digamos que tenemos una 'Colección ' en su lugar, ¿podemos hacer esencialmente lo mismo pero en lugar de necesitar que un elemento sea 'igual', podríamos tener un elemento MATCH usando' LIKE'? – dominicbri7

+3

@ dominicbri7 en una [pregunta] relacionada (http://stackoverflow.com/questions/7066122/how-to-make-a-like-query-to-elementcollection-of-type-map?rq=1) Encontré la solución. Use el método join en la clase Root 'cb.like (from.join (" apples "). Get (" color "), textParameter)' – cirovladimir

1

Sólo otra manera usando EN

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


(...) 
} 

A continuación, puede escribir una consulta criterios como

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