45

我有一个字符串中的 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零件工作?谢谢。

4

3 回答 3

75

您的 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

于 2010-06-27T04:27:15.087 回答
11

如果您不幸使用较旧的非 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();
于 2015-04-13T18:52:33.840 回答
1

即使您的查询正确执行,如果您的查询参数包含太多值,您也可能会遇到错误。

如果您使用的是 Hibernate 5.1 或更高版本,则此问题的一种可能解决方案是使用 Session.byMultipleIds()。

session
    .byMultipleIds(TrackedItem.class)
    .multiLoad(1L, 2L, 3L);

有关更多信息,请参阅https://thoughts-on-java.org/fetch-multiple-entities-id-hibernate/

于 2019-02-12T08:35:48.050 回答