修正 Hibernate 錯誤“DuplicateMappingException:實體映射中的列重複”
1.概述
在這個簡短的教程中,我們將重點介紹如何修復 Hibernate 錯誤「 DuplicateMappingException: Column is duplicated in mapping for entity
」。
首先,我們來看看異常的主要原因。然後,我們將使用實際範例演示如何重現它。然後,我們最終會解決它。
2. 理解DuplicateMappingException
在繼續解決方案之前,讓我們花點時間來了解異常。
簡而言之, DuplicateMappingException
是MappingException
的子類,它為重複的物件關係映射提供更具體的錯誤處理。
此外,當同一列在實體類別中被對應多次時,會出現訊息「 Column is duplicated in mapping for entity
」 。在這種情況下,Hibernate不知道如何處理重複。
3. 重現DuplicateMappingException
現在我們知道了導致 Hibernate 因DuplicateMappingException
而失敗的原因,讓我們捲起袖子並在實踐中重現它。
首先,我們來考慮一下Person
實體類別:
@Entity
public class Person {
@Id
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "first_name") // oh no!
private String lastName;
// standard getters and setters
}
簡而言之,一個人由標識符、名字和姓氏來定義。 @Entity
註解顯示Person
類別是一個 JPA 實體,而@Id
註解表示主鍵。此外, @Column
註釋將每個實體欄位對應到特定的表格列。
如我們所見,我們假設將兩個欄位firstName
和lastName,
對應到同一列first_name
。現在,讓我們使用測試案例來查看異常:
@Test
void whenDuplicatingColumnMapping_thenThrowMappingException() {
assertThatThrownBy(() -> {
session = HibernateUtil.getSessionFactory()
.openSession();
session.beginTransaction();
session.createQuery("FROM Person", Person.class)
.list();
session.close();
}).isInstanceOf(DuplicateMappingException.class)
.hasMessageContaining("Column 'first_name' is duplicated in mapping for entity");
}
如上所示,Hibernate 拋出DuplicateMappingException
,因為我們使用同一列來對應欄位firstName
和lastName
。
4. 修復異常
正如我們前面提到的, DuplicateMappingException
的根本原因是將同一列綁定到多個欄位。因此,最簡單的解決方案是將每個欄位對應到一個唯一的列。
首先,讓我們更新Person
類別並將lastName
屬性對應到另一列:
@Column(name = "last_name")
private String lastName;
現在,我們將建立另一個測試以確保一切按預期進行:
@Test
void whenNotDuplicatingColumnMapping_thenCorrect() {
session = HibernateUtil.getSessionFactory()
.openSession();
session.beginTransaction();
assertThat(session.createQuery("FROM Person", Person.class)
.list()).isEmpty();
session.close();
}
不出所料,測試用例成功執行並且沒有因DuplicateMappingException
而失敗。
5. 結論
在這篇短文中,我們討論了導致 Hibernate 拋出DuplicateMappingException
的原因: Column is duplicated in mapping for entity
。然後我們展示瞭如何解決它。可以在 GitHub 上找到此異常的重現器。