2

更新 問題が見つかりました。ちょっと恥ずかしい。クライアント側のコードは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>  
4

1 に答える 1

0

id 属性が次のタイプであると仮定しますLong

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

次に、クエリが機能する必要があり、基準も機能します

于 2013-01-17T19:36:59.133 に答える