2013-01-17 48 views
2

UPDATE 我發現了這個問題。有點尷尬。客戶端代碼發送了一個Set的1元素,它是報告ID的串聯字符串。 AARGH!當使用Hibernate for Java獲取異常行爲綁定HQL中的parameterList時


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

這是非常不正常的,因爲如果你注意到的最後綁定聲明它認爲集了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單獨結合。

我完全被這種奇怪的行爲所迷惑。也許你們中的一些人可以指出我做錯了什麼。

FYI的標準構造我用(&其導致相同的輸出)是像這樣,

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

P.S.我還使用了一個名爲SQL查詢與相同的結果

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

你嘗試使用調試器進入setParameterList方法?確保它在兩種情況下都採用相同的方法實現將會很有趣。在第一個場景中進入setParameterList(String,Object),在第二個場景中進入setParameterList(String,Collection)。 –

+0

@mattforsythe其實我發現了我的客戶端代碼,這是餵養報告ID是錯誤的。當它遇到一個數組時,它沒有正確地序列化它。這導致了一組1元素,這是一系列報告標識符。 – Chantz

+0

但是在你提到的問題中,一個集合包含兩個'String'類型的元素。 –

回答

0

假設id屬性的類型爲Long

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

那麼查詢應該工作的,該標準也適用

相關問題