2011-06-08 33 views
20

我知道我可以將列表傳遞給JPA中的命名查詢,但NamedNativeQuery怎麼樣?我嘗試了很多方法,但仍然無法將列表傳遞給NamedNativeQuery。任何人都知道如何將列表傳遞給NamedNativeQuery中的in子句?非常感謝你!JPA在命名本機查詢中將列表傳遞給IN子句

的NamedNativeQuery是如下:

@NamedNativeQuery(
    name="User.findByUserIdList", 
    query="select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
     "where u.user_id in (?userIdList)" 
) 

,它被稱爲是這樣的:

List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList(); 

但是結果並不如我所料。

System.out.println(userList.size()); //output 1 

Object[] user = userList.get(0); 
System.out.println(user.length); //expected 5 but result is 3 
System.out.println(user[0]);  //output MDAVERSION which is not a user_id 
System.out.println(user[1]);  //output 5 
System.out.println(user[2]);  //output 7 
+0

你試過執行準確使用DB客戶端相同的查詢? – 2011-06-08 11:39:27

回答

14

列表不是在JDBC中綁定的原生SQL查詢的有效參數。您需要爲列表中的每個參數都有一個參數。

其中u.user_id在(?ID1,?ID2)

這是通過JPQL支持,但不是SQL,所以你可以使用JPQL不是本機查詢。

某些JPA提供商可能會支持此功能,因此您可能需要向提供商記錄一個錯誤。

+3

問題如何... – SoftwareSavant 2012-07-10 16:21:43

1

嘗試在JPA2與Hibernate作爲提供程序,似乎冬眠不支持在列表中「IN」,它的工作原理。 (至少對於已命名的查詢,我相信它將與已命名的NATIVE查詢類似) hibernate在內部做了什麼,生成動態參數,IN內部與傳入列表中的元素數量相同。

所以在上面

List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList(); 

您例如如果列表中有2種元素的查詢將看起來像

select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
     "where u.user_id in (?, ?) 

,如果它有3個要素,它看起來像

select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
     "where u.user_id in (?, ?, ?) 
-1

你可以試試這個:userIdList而不是(?userIdList)

@NamedNativeQuery(
     name="User.findByUserIdList", 
     query="select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
      "where u.user_id in :userIdList" 
) 
0

根據數據庫/供應商/驅動器/等等,你可以,事實上,通過列表中的綁定參數到JPA本地查詢。例如,使用Postgres和EclipseLink,以下工作(返回true),演示多維數組以及如何獲得雙精度數組。 (做SELECT pg_type.* FROM pg_catalog.pg_type用於其他類型的;可能與_的那些,但在使用前剝去其關閉)

Array test = entityManager.unwrap(Connection.class).createArrayOf("float8", new Double[][] { { 1.0, 2.5 }, { 4.1, 5.0 } }); 
Object result = entityManager.createNativeQuery("SELECT ARRAY[[CAST(1.0 as double precision), 2.5],[4.1, 5.0]] = ?").setParameter(1, test).getSingleResult(); 

鑄造是有這麼字面陣列雙打而不是數字的。

更重要的問題 - 我不知道如何或如果你可以做命名查詢;也許,我認爲這取決於。但是我認爲以下內容適用於Array的東西。

Array list = entityManager.unwrap(Connection.class).createArrayOf("int8", arrayOfUserIds); 
List<Object[]> userList = entityManager.createNativeQuery("select u.* from user u "+ 
    "where u.user_id = ANY(?)") 
    .setParameter(1, list) 
    .getResultList(); 

我沒有相同的模式OP,所以我沒有檢查這完全是,但我認爲它應該工作 - 再次,至少在Postgres的&的EclipseLink。

而且,關鍵是發現:http://tonaconsulting.com/postgres-and-multi-dimensions-arrays-in-jdbc/

相關問題