使用 JPQL 将列表传递给 WHERE IN 子句会导致 IllegalArgumentException
Passing list to WHERE IN clause with JPQL causes IllegalArgumentException
今天我在尝试使用 Hibernate 和 JPQL 通过对象的 ID 从数据库中获取对象时发现了一个(奇怪的)问题。
我调用的方法是:
List<User> userList = userDao.findUsersByIds(ids);
详情:
@Repository
public interface UserDao extends JpaRepository<User, Long> {
(...)
@Query("SELECT u FROM User u " +
"WHERE u.id IN :ids")
List<User> findUsersByIds(@Param("ids") List<Long> ids);
}
我 运行 不知道这个问题的根本原因可能是什么,因为传递的列表是 List<Long>
类型的。
不过,它会导致以下堆栈跟踪:
Caused by: java.lang.IllegalArgumentException: Parameter value element [37] did not match expected type [java.lang.Long (n/a)]
at org.hibernate.query.spi.QueryParameterBindingValidator.validateCollectionValuedParameterBinding(QueryParameterBindingValidator.java:77) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:46) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.QueryParameterListBindingImpl.validate(QueryParameterListBindingImpl.java:75) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.QueryParameterListBindingImpl.setBindValues(QueryParameterListBindingImpl.java:33) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameterList(AbstractProducedQuery.java:568) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:490) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:106) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_144]
试试这个(查询方法,如果你使用 spring):
List<User> findAllByIdIn(List<Long> id);
或 JPQL:
@Query("SELECT u FROM User u WHERE u.id IN ?1")
List<User> findUsersByIds(List<Long> id);
今天我在尝试使用 Hibernate 和 JPQL 通过对象的 ID 从数据库中获取对象时发现了一个(奇怪的)问题。
我调用的方法是:
List<User> userList = userDao.findUsersByIds(ids);
详情:
@Repository
public interface UserDao extends JpaRepository<User, Long> {
(...)
@Query("SELECT u FROM User u " +
"WHERE u.id IN :ids")
List<User> findUsersByIds(@Param("ids") List<Long> ids);
}
我 运行 不知道这个问题的根本原因可能是什么,因为传递的列表是 List<Long>
类型的。
不过,它会导致以下堆栈跟踪:
Caused by: java.lang.IllegalArgumentException: Parameter value element [37] did not match expected type [java.lang.Long (n/a)]
at org.hibernate.query.spi.QueryParameterBindingValidator.validateCollectionValuedParameterBinding(QueryParameterBindingValidator.java:77) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:46) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.QueryParameterListBindingImpl.validate(QueryParameterListBindingImpl.java:75) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.QueryParameterListBindingImpl.setBindValues(QueryParameterListBindingImpl.java:33) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameterList(AbstractProducedQuery.java:568) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:490) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:106) ~[hibernate-core-5.3.3.Final.jar:5.3.3.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_144]
试试这个(查询方法,如果你使用 spring):
List<User> findAllByIdIn(List<Long> id);
或 JPQL:
@Query("SELECT u FROM User u WHERE u.id IN ?1")
List<User> findUsersByIds(List<Long> id);