164

I have built a NamedQuery that looks like this:

@NamedQuery(name = "EventLog.viewDatesInclude",
        query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND "
        + "el.timeMark <= :dateTo AND "
        + "el.name IN (:inclList)")

What I want to do is fill in the parameter :inclList with a list of items instead of one item. For example if I have a new List<String>() { "a", "b", "c" } how do I get that in the :inclList parameter? It only lets me codify one string. For example:

setParameter("inclList", "a") // works

setParameter("inclList", "a, b") // does not work

setParameter("inclList", "'a', 'b'") // does not work

setParameter("inclList", list) // throws an exception

I know I could just build a string and build the whole Query from that, but I wanted to avoid the overhead. Is there a better way of doing this?

Related question: if the List is very large, is there any good way of building query like that?

1

4 Answers 4

225

When using IN with a collection-valued parameter you don't need (...):

@NamedQuery(name = "EventLog.viewDatesInclude", 
    query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND " 
    + "el.timeMark <= :dateTo AND " 
    + "el.name IN :inclList") 
Sign up to request clarification or add additional context in comments.

6 Comments

Nope ... I my case its opposite. If I use :inclList then its not working. If I use IN (:inclList) then it works.
Also note mentioning: the type of your param has to be an collection (not an array) of objects. The objects must match the type of the field. .toString() is no substitute for class String
I think this is something that has changed with the versions of Hibernate, as far as I can remember I have gotten an error when not having the paranthesis around the variable when using IN. Strange if it's not backwards compatible..
This was indeed an hibernate bug (the need of parenthesis) that's been fixed in 3.6.1
For related question: In case of very large list there could be limitations for the in implementation. E.g. oracle 11g. max. 1000 list elements as parameter are possible. A workaround is to chop the list in subLists and collect the results. JPA itself does not restrict the list size.
|
107

The proper JPA query format would be:

el.name IN :inclList

If you're using an older version of Hibernate as your provider you have to write:

el.name IN (:inclList)

but that is a bug (HHH-5126) (EDIT: which has been resolved by now).

1 Comment

Thank you for distinguishing the older versions of Hibernate use ()
38
public List<DealInfo> getDealInfos(List<String> dealIds) {
        String queryStr = "SELECT NEW com.admin.entity.DealInfo(deal.url, deal.url, deal.url, deal.url, deal.price, deal.value) " + "FROM Deal AS deal where deal.id in :inclList";
        TypedQuery<DealInfo> query = em.createQuery(queryStr, DealInfo.class);
        query.setParameter("inclList", dealIds);
        return query.getResultList();
    }

Works for me with JPA 2, Jboss 7.0.2

1 Comment

Thank you for showing a brief but complete example.
24

You should convert to List as shown below:

    String[] valores = hierarquia.split(".");       
    List<String> lista =  Arrays.asList(valores);
    
    String jpqlQuery = "SELECT a " +
            "FROM AcessoScr a " +
            "WHERE a.scr IN :param ";
    
    Query query = getEntityManager().createQuery(jpqlQuery, AcessoScr.class);                   
    query.setParameter("param", lista);     
    List<AcessoScr> acessos = query.getResultList();

2 Comments

Thx this answer helped me
This is best answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.