Hibernate: Select entities where collection contains all of the specified valus

前端 未结 3 1706
闹比i
闹比i 2020-12-16 06:31

I need assistance with a tricky hibernate query problem. I have the following entities:

public class Book {
   private String bookId;
   private String autho         


        
相关标签:
3条回答
  • 2020-12-16 06:54

    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)

    0 讨论(0)
  • 2020-12-16 06:57

    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.

    0 讨论(0)
  • 2020-12-16 07:00

    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!

    0 讨论(0)
提交回复
热议问题