简体   繁体   中英

When using Hibernate for Java getting abnormal behavior binding parameterList in HQL

UPDATE I found the issue. Kind of embarrassing. The client side code was sending a Set of 1 element which was the concatenated String of the report Ids. AArgh!


I am using hibernate v3.6.4 in my Java project. I am getting problems when trying to use a parameter list for a named parameter in my HQL query.

Basically I want to get all the records which match one of the " id "s mentioned in the IN clause.

I tried using both HQL & Criteria I get the same result.

My HQL query,

Set<String> reportIds = new HashSet<String>();
reportIds.add("1");
reportIds.add("2");

String whereClause = "from Report where id IN (:reportIds) ";
Query query = session.createQuery(whereClause);
query.setParameterList("reportIds", reportIds);

Output = empty list. Although I checked by firing manual sql queries in the terminal that there are indeed such records.

I turned on the logging and here is what I see,

Hibernate: 
    /* 
from
    Report 
where
    id IN (
        :ids
    ) */ select
        mediavalue0_.id as id31_,
        ...

    from
        report mediavalue0_ 
    where
        mediavalue0_.id in (
            ?
        )
HibernateLog --> 13:22:36 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - 1,2

This is very abnormal because if you notice the final bind statement it considers the toString of the Set! ie "1,2" instead of "1" and then "2"!

I was messing around with it so on a whim I decided to directly create the instance of the set inside the setParameterList method call itself. Like so,

query.setParameterList("reportIds", Sets.newHashSet("1","2"));

And it worked! BTW Sets.newHashSet is a construct provided google's guava library. I use the same library to generate the original reportIds set. So there is no inconsistency there.

This query translates to following TRACE,

from
    Report 
where
    id IN (
        :ids
    ) */ select
        mediavalue0_.id as id31_,
        ...
    from
        report mediavalue0_ 
    where
        mediavalue0_.id in (
            ? , ?
        )
HibernateLog --> 13:28:57 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - 1
HibernateLog --> 13:28:57 TRACE org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - 2

Notice the separate binds for VARCHAR.

I am totally flummoxed by this odd behavior. Maybe some of you guys can point out what I am doing wrong.

FYI the criteria construct I used (& which resulted in the same output) is like so,

Criteria criteria = session.createCriteria(Report.class);
criteria.add(Restrictions.in("id", reportIds));

PS I also used a named sql query with same result

<sql-query name="reportByIds">
    <return class="report.Report"/>
    SELECT mvr.* from report mvr
    WHERE mvr.id IN :ids
</sql-query>  

Assume id attribute is of type Long

Set<Long> reportIds = new HashSet<Long>();
reportIds.add(1l);
reportIds.add(2l);

then the query should work, the criteria also works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM