修正 Hibernate QueryException:命名參數未綁定
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;
// standard getters and setters
}
這裡, @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”
的原因。然後,我們透過一個實際範例說明如何重現異常以及如何修復它。
與往常一樣,範例的完整原始程式碼可 在 GitHub 上取得。