Hibernate 异常 QueryException: “named parameter not bound”.

1、概览

本文将带你了解如何解决 Hibernate 异常 QueryException: “named parameter not bound”

2、理解异常

简而言之,在将 Hibernate 查询转换为 SQL 时,由于语法无效,Hibernate 会抛出 QueryException 来提示错误。“named parameter not bound” 表明 Hibernate 无法绑定特定查询中指定的命名参数。

通常情况下,命名参数的前缀是冒号(:),后面是一个占位符,表示在执行查询之前需要设置的实际值:

SELECT p FROM Person p WHERE p.firstName = :firstName;

造成异常的最常见原因之一是忘记为 Hibernate 查询中的命名参数赋值

3、重现异常

理解了导致异常的原因后,通过一个实际的例子来重现这个异常。

创建如下 Person 实体类:

@Entity
public class Person {

    @Id
    private int id;
    private String firstName;
    private String lastName;

   // 标准的 Get、Set
}

如上,@Entity 注解表示类是一个实体,它映射了数据库中的一个表。此外,@Id 表示 id 属性代表主键。

现在,创建一个带有命名参数的 Hibernate 查询,并假装忘记为参数设置值:

@Test
void whenNotSettingValueToNamedParameter_thenThrowQueryException() {
    Exception exception = assertThrows(QueryException.class, () -> {
        Query<Person> query = session.createQuery("FROM Person p WHERE p.firstName = :firstName", Person.class);
        query.list();
    });

    String expectedMessage = "Named parameter not bound";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

如你所见,测试用例抛出了异常 QueryException: “named parameter not bound”。原因是 Hibernate 不知道命名参数 firstName 的任何信息,并希望在执行查询前设置该参数。

4、修复异常

在这种情况下,避免 QueryException 的解决方案是在执行查询之前为命名的参数赋值。为此,可以使用 setParameter() 方法:

@Test
void whenSettingValueToNamedParameter_thenDoNotThrowQueryException() {
    Query<Person> query = session.createQuery("FROM Person p WHERE p.firstName = :firstName", Person.class);
    query.setParameter("firstName", "Azhrioun");

    assertNotNull(query.list());
}

如上图所示,测试用例成功通过。setParameter() 调用告诉 Hibernate 在执行查询时使用哪个值作为命名参数。

5、总结

本文介绍了导致 Hibernate 抛出异常 QueryException: “named parameter not bound” 的原因,以及如何修复该异常。


Ref:https://www.baeldung.com/hibernate-queryexception-named-parameter-not-bound-fix