更新
我发现了问题。有点尴尬。客户端代码正在发送一个Set
1 元素,它是报告 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>