繁体   English   中英

使用Hibernate for Java时,HQL中的异常行为绑定parameterList

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

更新我发现了问题。 有点尴尬。 客户端代码正在发送Set 1元素,该元素是报表ID的串联字符串。 啊!


我在Java项目中使用的是Hibernate v3.6.4。 尝试在HQL查询中为命名参数使用参数列表时遇到问题。

基本上,我想获取与IN子句中提到的“ id ”之一匹配的所有记录。

我尝试同时使用HQL和条件我得到了相同的结果。

我的HQL查询

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);

输出=空列表。 尽管我通过在终端中触发手动sql查询来检查确实存在此类记录。

我打开了日志记录,这就是我所看到的,

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

这是非常不正常的,因为如果您注意到最终的bind语句,它将考虑Set的toString! 即“ 1,2”,而不是“ 1”,然后是“ 2”!

我搞砸了,所以一时兴起,我决定直接在setParameterList方法调用本身内部创建该set的实例。 像这样

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

而且有效! BTW Sets.newHashSet是Google的番石榴库提供的结构。 我使用相同的库来生成原始的reportIds集。 因此,那里没有任何不一致之处。

该查询翻译为以下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

注意VARCHAR的单独绑定。

我完全被这种奇怪的行为弄糊涂了。 也许有些人可以指出我做错了什么。

仅供参考,我使用的条件构造(&导致相同的输出)就像这样,

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

PS我也使用了具有相同结果的命名的sql查询

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

假设id属性的类型为Long

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

则查询应该有效,条件也有效

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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