I need assistance with a tricky hibernate query problem. I have the following entities:
public class Book {
private String bookId;
private String autho
The accepted answer from JB Nizet is good but will not work if your collection can contain duplicates (might be a valid reason for that, probably not with the tag example though).
Lets say the collection for some books can contain duplicate tags with the same name "MyTag". Then a search for the Tags "MyTag", "YourTag" could return books that have 2 "MyTag" tags but no "YourTag" tag.
select b from Book b where :numberOfTags = (select count(distinct tag.tagName) from Book b2 inner join b2.tags tag where b2.id = b.id and tag.tagName IN (:tagNames))
As I said nothing wrong with the accepted answer but if you need to support duplicates in the collection then you need to add count(distinct tag.name)
You could use the following query:
select book from Book book
where :numberOfTags = (select count(tag.id) from Book book2
inner join book2.tags tag
where book2.id = book.id
and tag in (:tags))
where numberOfTags
is the number of tags in the set of tags that must be matched.
I would advice you to create two custom functions or restriction as :
collect(book.tags) -> returns list of tags associated with the book
containsAll(bookTagsList, tags) --> validates and returns true if all
tags elements are present in bookTagsList
returned by the first function "collect"
Once functions are defined and registered, you would be able to run HQL/criteria query like:
from Book book where containsAll(collect(book.tags), :tags)
or
session.createCriteria(Book.class).add(
Restrictions.add(collect("tags").containsAll(tags))
).list();
Please Note: This is just a sample pseudo code to share the idea.
Hope this helps!