Hibernate 异常 “QueryParameterException: No Argument for Ordinal Parameter”
1、概览
本文将带你了解 Hibernate 出现 QueryParameterException: “no argument for ordinal parameter” 异常的原因以及解决办法。
2、理解异常
通常,Hibernate 会抛出 QueryParameterException 来提示查询参数出现问题。它表示指定的参数无效或未找到。
此外,“no argument for ordinal parameter(没有设置指定顺序的参数)” 消息表示 Hibernate 无法为定义的参数找到合适的参数。导致这种异常的常见原因是在 Hibernate 查询中忘记了为已定义的参数提供值。
3、实际案例
知道了 Hibernate 出现 QueryParameterException 异常的原因后,让我们通过一个实际的例子来看看如何重现它。
首先,来看看 Employee
实体类:
@Entity
public class Employee {
@Id
private int id;
private String firstName;
private String lastName;
// 标准的 Getter 和 Setter
}
如上,Employee
有 id
、firstName
和 lastName
字段。
@Entity
注解用于指定 Employee
类是一个 JPA 实体,而 @Id
注解则标记了表示主键的字段。
接着,创建一个包含两个参数的 HQL 查询,并假装忘记为第二个参数指定值:
@Test
void whenMissingParameter_thenThrowQueryParameterException() {
assertThatThrownBy(() -> {
String selectQuery = """
FROM Employee
WHERE firstName = ?1
AND lastName = ?2
""";
Query<Employee> query = session.createQuery(selectQuery, Employee.class);
query.setParameter(1, "Jean");
query.list();
}).isInstanceOf(QueryParameterException.class)
.hasMessageContaining("No argument for ordinal parameter");
}
可以看到,Hibernate 抛出了异常,因为我们没有使用 setParameter()
为 lastName
参数设置值。
4、修复异常
解决 QueryParameterException
的最简单方法就是在执行查询之前为第二个参数指定一个有效值。
添加一个新的测试用例,并使用 setParameter()
设置姓氏:
@Test
void whenDefiningAllParameters_thenCorrect() {
String selectQuery = """
FROM Employee
WHERE firstName = ?1
AND lastName = ?2
""";
Query<Employee> query = session.createQuery(selectQuery, Employee.class);
query.setParameter(1, "Jean")
.setParameter(2, "Smith");
assertThat(query.list()).isNotNull();
}
不出所料,测试用例成功执行,没有出现 QueryParameterException
异常。
5、总结
本文介绍了导致 Hibernate 出现异常 QueryParameterException: “no argument for ordinal parameter” 的原因,以及如何修复该异常。
Ref:https://www.baeldung.com/hibernate-fix-queryparameterexception