我在String中有一个ID列表,并希望使用Hibernate来获取具有这些ID的行。 TrackedItem
是一个Hibernate / JPA实体(对不起,如果我在这里混淆了命名)。
我的代码是:
String idsText = "380, 382, 386";
ArrayList<Long> ids = new ArrayList<Long>();
for (String i : idsText.split(","))
{
ids.add(Long.getLong(i));
}
List<TrackedItem> items = TrackedItem.find("id IN (?)", ids).fetch();
但那失败了:
JPAQueryException occured : Error while executing query from models.TrackedItem where id IN (?): java.util.ArrayList cannot be cast to java.lang.Long
如何让IN
部分工作?感谢。
答案 0 :(得分:59)
您的JPQL查询的语法不正确。使用(带位置参数):
List<Long> ids = Arrays.asList(380L, 382L, 386L);
Query query = em.createQuery("FROM TrackedItem item WHERE item.id IN (?1)");
query.setParameterList(1, ids)
List<TrackedItem> items = query.getResultList();
或(使用命名参数):
List<Long> ids = Arrays.asList(380L, 382L, 386L);
Query query = em.createQuery("FROM TrackedItem item WHERE item.id IN :ids");
query.setParameterList("ids", ids)
List<TrackedItem> items = query.getResultList();
下面是JPA 1.0规范中有关参数的相关部分:
4.6.4.1位置参数
以下规则适用于位置参数。
- 输入参数由问号(?)前缀后跟一个整数指定。例如:
?1
。- 输入参数从1开始编号 请注意,在查询字符串中可以多次使用相同的参数,并且查询字符串中参数的使用顺序不必符合位置参数的顺序。
4.6.4.2命名参数
命名参数是以“:”符号为前缀的标识符。它遵循第4.4.1节中定义的标识符规则。命名参数区分大小写。
示例:
SELECT c FROM Customer c WHERE c.status = :stat
第3.6.1节描述了用于绑定命名查询参数的API
答案 1 :(得分:10)
如果你不幸使用较旧的非JPA休眠,这应该适合你:
Query query = session.createQuery("FROM TrackedItem item WHERE item.id IN (:items)");
query.setParameterList("items", Arrays.asList(380L, 382L, 386L));
@SuppressWarnings("unchecked")
List<TrackedItem> results = query.list();
答案 2 :(得分:0)
即使查询正确执行,如果查询参数包含太多值,您也可能会遇到错误。
如果使用的是Hibernate 5.1或更高版本,此问题的一种可能解决方案是使用Session.byMultipleIds()。
session
.byMultipleIds(TrackedItem.class)
.multiLoad(1L, 2L, 3L);
有关更多信息,请参见https://thoughts-on-java.org/fetch-multiple-entities-id-hibernate/