更新
問題が見つかりました。ちょっと恥ずかしい。クライアント側のコードはSet
、レポート ID の連結された文字列である 1 つの要素を送信していました。ああああ!
Java プロジェクトで hibernate 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 は、Google の guava ライブラリが提供するコンストラクトです。同じライブラリを使用して、元の 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>