Especificación Jpa para encontrar un subset del valor del campo

Estoy escribiendo una aplicación web usando Spring Data JPA en la capa de persistencia, más específicamente, mis DAO amplían la interfaz JpaSpecificationExecutor , por lo que puedo implementar algún tipo de filter; imagine la list de Item con varios attributes (omito las annotations y otros metadatos en aras de la claridad):

 data class Item(var tags: MutableList<String>) 

En mi capa de service, mi método de filter se ve así:

 fun findBy(tagsToFilterBy: List<String>): List<Items> { return dao.findAll { root, query, builder -> builder.//?? } } 

Lo que quiero lograr es recuperar solo los Item que contienen exactamente esas tagsToFilterBy , en otras palabras, tagsToFilterBy debe ser un subset de Item.tags .

Conozco el método isMember(...) , pero creo que su uso no sería muy agradable con muchas tags, ya que solo acepta una única "entidad" en el momento de la llamada. ¿Podrías aconsejarme algo?

Mi otra pregunta es si es seguro usar la input del usuario directamente en digamos builder.like(someExpression, inputFromUser) o tengo que ponerlo en el builder.parameter(...) y luego query.setParameter(...) .

Gracias por cualquier idea

    Una forma es usar filter y probar cada elemento para ver si su list de filters lo contiene.

     val result = dao.filter { tagsToFilterBy.contains(it.tag) } 

    Para acelerarlo, podría forzar la sorting de su list de filters, y tal vez usar binarySearch , pero la mejora del performance (o no) dependería del tamaño de la list de filters. Por ejemplo, asumiendo que tagsToFilterBy está orderado, entonces:

     val result2 = dao.filter { tagsToFilterBy.binarySearch(it.tag) >= 0 } 

    La página de la Colección Kotlin describe cada uno de estos methods de extensión.

    Así que me las arreglé para escribir solo. No digo que sea bonita, pero es la más bonita, podría venir con:

     dao.findAll { root, query, builder -> val lst = mutableListOf<Pnetworkingicate>() val tagsPath = root.get<List<Tag>>("tags") tagsToFilterBy.forEach { lst.add(cb.isMember(it, tagsPath)) } cb.or(*lst.toTypedArray()) } 

    Esto básicamente pasa por las tags dadas, y verifica si es miembro de las tags o no.