如何修復 Hibernate UnknownEntityException:無法解析根實體
1. 概述
在這個簡短的教學中,我們將闡明如何解決 Hibernate UnknownEntityException: “Could not resolve root entity”.
首先,我們將解釋導致異常的根本原因。然後,我們將說明如何在實踐中重現和修復它。
2. 理解異常
在跳到解決方案之前,讓我們花點時間來了解異常及其堆疊追蹤。
通常,Hibernate 會拋出「 UnknownEntityException: Could not resolve root entity”
來表示無法解析 HQL 或 JPQL 查詢中的已知映射實體名稱。
簡而言之,Hibernate 依賴 JPA 實體來完成物件關係映射的所有繁重工作。因此,它期望查詢中指定的實體名稱與@Entity
註解所註解的類別名稱相符。
因此,導致異常的最常見原因之一是使用與有效實體類別名稱不符的名稱。
3. 實際例子
現在我們知道了 Hibernate 因UnknownEntityException
失敗的原因,讓我們深入研究如何在實踐中重現它。
首先,讓我們考慮一下Person
實體類別:
@Entity
public class Person {
@Id
private int id;
private String firstName;
private String lastName;
// standard getters and setters
}
在此範例中,我們透過標識符、名字和姓氏來定義一個人。
這裡,我們使用@Entity
註解來指示Person
類別是一個JPA實體。此外, @Id
表示代表主鍵的欄位。
接下來,我們將假裝在 HQL 查詢中使用錯誤的實體名稱。例如,讓我們嘗試選擇使用PERSON
作為實體名稱而不是Person
所有人員:
class UnknownEntityExceptionUnitTest {
private static Session session;
@BeforeAll
static void init() {
session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
}
@AfterAll
static void clear() {
session.close();
}
@Test
void whenUsingUnknownEntity_thenThrowUnknownEntityException() {
assertThatThrownBy(() -> session.createQuery("FROM PERSON", Person.class))
.hasRootCauseInstanceOf(UnknownEntityException.class)
.hasRootCauseMessage("Could not resolve root entity 'PERSON'");
}
}
正如我們所看到的,測試案例失敗,並出現UnknownEntityException: Could not resolve root entity
因為 Hibernate 無法將PERSON
識別為有效的 JPA 實體。
4. 修復異常
正如我們之前提到的,Hibernate 拋出UnknownEntityException
的主要原因是它無法找到具有指定名稱的實體。因此,最簡單的解決方案是在 HQL 和 JPQL 查詢中使用正確的實體名稱。
因此,讓我們新增一個新的測試案例並將錯誤的名稱PERSON
替換為Person
:
@Test
void whenUsingCorrectEntity_thenReturnResult() {
Query<Person> query = session.createQuery("FROM Person", Person.class);
assertThat(query.list()).isEmpty();
}
如上所示,測試案例成功執行,並且沒有失敗並出現異常,因為我們這次使用了Person
,這是一個有效的實體名稱。
5. 結論
在這篇短文中,我們了解了導致 Hibernate 因UnknownEntityException: “Could not resolve root entity”
。然後,我們透過一個實際例子來示範如何重現異常以及如何解決它。
與往常一樣,範例的完整原始程式碼可 在 GitHub 上取得。