2011-06-08 37 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/

相关问题