修復 Hibernate AnnotationException:欄位是 @ManyToOne 關聯,可能無法使用 @Column
1.概述
在這個簡短的教程中,我們將闡明如何修復 Hibernate 異常: “AnnotationException: field is a @ManyToOne association and may not use @Column to specify column mappings (use @JoinColumn instead)”
。
首先,我們將解釋異常背後的根本原因。然後,我們將透過實際範例說明如何重現該異常,最後說明如何修復它。
2. 理解AnnotationException
在跳到解決方案之前,讓我們先分解異常及其堆疊追蹤以了解發生了什麼。
Hibernate 依靠註解來完成將 Java 類別對應到資料庫表的所有繁重工作。通常,當 Hibernate 無法理解這些註解時,就會引發AnnotationException
異常。
此外, “is a @ManyToOne association and May Not Use @Column”
這則訊息表明@Column
註解被用在了不合理的位置。導致此異常的一個常見原因是,用@Column
修飾了已經使用@ManyToOne
映射的欄位。
3. 重現AnnotationException
現在我們了解了觸發 Hibernate 的AnnotationException
原因,讓我們深入研究並自行重新建立例外狀況。
首先,讓我們建立University
JPA 實體類別:
@Entity
public class University {
@Id
private int id;
@Column(name = "university_name")
private String name;
// standard getters and setters
}
簡而言之,每所大學都有一個識別符和一個名稱。 @Entity
註解將University
類別標記為 JPA 實體, @Id
指定其主鍵。此外, @Column
註解將欄位name
對應到其對應的資料庫列。
接下來,我們將建立另一個實體類別Student
:
@Entity
public class Student {
@Id
private int id;
@Column(name = "full_name")
private String fullName;
@ManyToOne
@Column(name = "university")
private University university;
// standard getters and setters
}
我們可以看到, Student
類別與University
類別共享多對一關聯。在這裡,我們假裝同時使用@Column
註解和@ManyToOne
註解。現在,讓我們使用測試案例重現該異常:
@Test
void whenUsingColumnAnnotationWithManyToOneAnnotation_thenThrowAnnotationException() {
assertThatThrownBy(() -> {
HibernateUtil.getSessionFactory()
.openSession();
}).isInstanceOf(AnnotationException.class)
.hasMessageContaining("university' is a '@ManyToOne' association and may not use '@Column'");
}
如上所示, Hibernate 失敗並拋出了AnnotationException
,因為我們在標有@ManyToOne
的欄位上使用了@Column
,這是錯誤的。這是因為在描述與連接相關的欄位時,Hibernate 需要與@Column
不同的註解。
4.解決方案
正如我們之前所看到的,當我們錯誤地嘗試在表示@ManyToOne
關係的欄位上使用@Column
時,會發生AnnotationException
。因此,最簡單的解決方法是改用@JoinColumn
註解。
首先,讓我們更新Student
類,用@JoinColumn
替換@Column
:
@ManyToOne
@JoinColumn(name = "university_id")
private University university;
這樣,我們就能確保 Hibernate 正確地對應外鍵關係,而不是將其視為一個簡單的欄位。接下來,讓我們編寫另一個測試案例來驗證一切是否正常運作:
@Test
void whenNotUsingColumnAnnotationWithManyToOneAnnotation_thenCorrect() {
Session session = HibernateUtil.getSessionFactory()
.openSession();
Query<Student> query = session.createQuery("FROM Student", Student.class);
assertThat(query.list()).isEmpty();
session.close();
}
正如預期的那樣,測試執行沒有問題,證實我們的修復可以防止AnnotationException
出現。
5. 結論
在這篇短文中,我們討論了導致 Hibernate 失敗並出現錯誤的原因:“ AnnotationException: field is a @ManyToOne association and may not use @Column to specify column mappings (use @JoinColumn instead)”
。在此過程中,我們演示瞭如何在實踐中重現異常以及如何解決它。