Cómo consultar entidades por su valor de colección
Frecuentes
Visto 37,422 veces
11
Estoy usando jpa y tengo la siguiente entidad:
@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",
joinColumns=@JoinColumn(name="folder_id")
)
@Column(name="product_id")
@NotNull
private Set<String> productsIds = new HashSet<String>();
}
Lo que quiero hacer es conseguir un conjunto de FavoritesFolder
entidades que contienen la cadena "favorite-id" en su productsIds
conjunto de miembros
Alguien sabe como se puede hacer en API de criterios?
Actualizar:
Estoy pensando que el siguiente sql debería funcionar, pero no estoy seguro de cómo hacerlo en ninguno de los dos. JPQL
or Criteria API
:
select * from favorites_folders join favorites_products on favorites_folders.id = favorites_products.folder_id where favorites_products.product_id = 'favorite-id'
3 Respuestas
17
Para obtener un conjunto de entidades FavoritesFolder que contengan la cadena "favorite-id" en su conjunto de miembros de Ids de productos utilizando la API de criterios, 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 sobre Colecciones en JPQL y consultas de criterios.
contestado el 23 de mayo de 12 a las 10:05
2
Solo otra forma de usar 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;
(...)
}
Luego puede escribir una consulta de 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);
}
respondido 28 nov., 13:22
0
Este es mi trabajo que funciona. Estoy usando Springboot 1.5.9. No tengo tiempo para identificar la causa raíz. Lo que sé es que esa propiedad anidada se ha ignorado al pasar JacksonMappingAwareSortTranslator
. Entonces, lo que hice para solucionar esto es no usar el objeto Ordenar creado por los resolutores. Aquí está mi código en Kotlin
. Sin hacer esto, el pageable.sort
is null
y la clasificación no funciona. Y mi código creará un nuevo PageRequest
objeto que tiene un valor no nulo sort
eso funciona.
@RequestMapping("/searchAds", method = arrayOf(RequestMethod.POST))
fun searchAds(
@RequestBody cmd: AdsSearchCommand,
pageable: Pageable,
resourceAssembler: PersistentEntityResourceAssembler,
sort: String? = null
): ResponseEntity<PagedResources<Resource<Ads>>> {
val page = adsService.searchAds(cmd, pageable.repairSortIfNeeded(sort))
resourceAssembler as ResourceAssembler<Ads, Resource<Ads>>
return adsPagedResourcesAssembler.toResource(page, resourceAssembler).toResponseEntity()
}
fun Pageable.repairSortIfNeeded(sort: String?): Pageable {
return if (sort.isNullOrEmpty() || this.sort != null) {
this
} else {
sort as String
val sa = sort.split(",")
val direction = if (sa.size > 1) Sort.Direction.valueOf(sa[1]) else Sort.Direction.ASC
val property = sa[0]
PageRequest(this.pageNumber, this.pageSize, direction, property)
}
}
Respondido el 02 de junio de 18 a las 13:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas jpa collections criteria-api or haz tu propia pregunta.
Sé que en este tema nos estamos refiriendo a ID y, por lo tanto, tienen que ser IGUALES para que coincidan, pero digamos que tenemos un
Collection<String>
en cambio, ¿podemos hacer esencialmente lo mismo pero en lugar de necesitar que un artículo seaequal
, podríamos tener un elemento COINCIDIR usandoLIKE
? - dominicbri7@dominicbri7 en un tema relacionado pregunta Encontré la solución. Use el método de unión en la clase raíz
cb.like(from.join("apples").get("color"), textParameter)
- cirovladimir