2

更新 我发现了问题。有点尴尬。客户端代码正在发送一个Set1 元素,它是报告 ID 的串联字符串。啊啊!


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

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

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

我的 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

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

我一直在搞乱它,所以一时兴起,我决定直接在setParameterList方法调用本身内创建集合的实例。像这样,

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

它奏效了!BTW Sets.newHashSet 是一个构造提供的谷歌的番石榴库。我使用相同的库来生成原始的 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>  
4

1 回答 1

0

假设 id 属性是类型Long

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

那么查询应该可以工作,条件也可以工作

于 2013-01-17T19:36:59.133 回答