1、概览 {#1概览}
本文将带你了解如何解决 Hibernate 异常 QueryException: "named parameter not bound"。
2、理解异常 {#2理解异常}
简而言之,在将 Hibernate 查询转换为 SQL 时,由于语法无效,Hibernate 会抛出 QueryException
来提示错误。"named parameter not bound" 表明 Hibernate 无法绑定特定查询中指定的命名参数。
通常情况下,命名参数的前缀是冒号(:
),后面是一个占位符,表示在执行查询之前需要设置的实际值:
SELECT p FROM Person p WHERE p.firstName = :firstName;
造成异常的最常见原因之一是忘记为 Hibernate 查询中的命名参数赋值。
3、重现异常 {#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、修复异常 {#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、总结 {#5总结}
本文介绍了导致 Hibernate 抛出异常 QueryException: "named parameter not bound" 的原因,以及如何修复该异常。
Ref:https://www.baeldung.com/hibernate-queryexception-named-parameter-not-bound-fix