具有该名称 [<name>] 的休眠参数不存在

hibernate parameter with that name [<name>] did not exist

我是运行下面的代码

UserService.java

String alias = "u";
String select = "SELECT u.email";
String where = "u.userId = :id";
Map<String, Object> params = new HashMap<>();
params.put("id", userId);

List<User> users = db.findRecords(User.class, alias, select, where, params);

DB.java

public <T> List<T> findRecords(Class<T> entityClass, String entityAlias, String select, String where, Map<String, Object> params) {
    String sql = select + " FROM " + entityClass.getName() + " " + entityAlias;

    if (where != null) {
        sql = sql + " WHERE " + where;
    }

    Query query = entityManager.createQuery(sql);
    System.out.println(sql);
    if (!params.isEmpty()) {
        Iterator<Entry<String, Object>> iterator = params.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, Object> entry = iterator.next();
            System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
            query.setParameter((String) entry.getKey(), (Long) entry.getValue());
        }
    }

    return query.getResultList();
}

我收到以下错误日志。

SELECT u.email FROM com.catalog.user.User u WHERE u.userId = :id
key: id, value: 28636907

Caused by: java.lang.IllegalArgumentException: Parameter with that name [id] did not exist

如果控制台中打印了参数,那么是什么导致出现非法参数异常?

请帮忙!

我认为这里的问题是由您从 Map 获取参数的方式引起的,使用 Map.entrySet() 方法迭代值仅在迭代内可用,并且在外部未定义其中,这就是参数在循环期间正确打印并且在查询中不存在的原因。

如果你看一下 Map.entry documentation 它说:

These Map.Entry objects are valid only for the duration of the iteration;

我建议你改变存储和使用参数的方式,你可以简单地使用一个 List<Object> 来存储参数或者直接在方法调用中传递 id 参数:

public <T> List<T> findRecords(Class<T> entityClass, String entityAlias, String select, String where, Long id){

然后直接在查询中追加这个值:

query.setParameter("id", id);

1) 检查参数名:id是否有错别字。它区分大小写。

2) 尝试不带参数执行查询。可能是实体映射的问题。

3) 尝试在没有HashMap 的情况下直接在查询中设置参数。