![](/img/trans.png)
[英]Should I write equals() and hashCode() methods in JPA entities?
[英]Should I use getters or fields in JPA entity equals methods?
為我的 JPA 實體編寫equals
方法時,我應該直接訪問這些字段,還是應該通過 getter 訪問 go?
換句話說,我這樣做了嗎?
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return Objects.equals(getIsbn(), book.getIsbn());
}
或這個?
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return Objects.equals(isbn, book.isbn);
}
在這種情況下,我將 JPA 注釋放在字段上還是放在 getter 上有關系嗎? 另外,如果我使用FetchType.LAZY
(我想它會)有關系嗎? 我在某處讀到,如果您按字段訪問並且注釋放在 getter 上(它們將保持null
或為空),惰性字段不會具體化,但是當注釋放在字段上時會發生這種情況嗎?
Hibernate 和其他供應商的行為是否不同?
我用谷歌搜索,甚至打開了一本書,但我是一個 JPA 菜鳥,我找不到這個問題的明確答案(盡管我確實注意到專家傾向於在他們的博客中使用吸氣劑,例如這篇文章) .
.equals
是在實體 class 內部定義的方法。為此,沒有理由使用任何getters
,因為即使是具有私有訪問修飾符的字段也可以直接從相同的 class 的方法訪問。
另外,如果我使用 FetchType.LAZY(我想它會)有關系嗎?
是的,從技術上講,這很重要,因為在為惰性字段調用equals
期間,您必須打開 entityManager 的 session,否則會發生眾所周知的LazyInitializationException
錯誤。 但是因為 spring 啟動默認為spring.jpa.open-in-view=true
它會短路這個錯誤,因為它保持 session 打開直到響應被處理給用戶。
因此,如果您使用Spring-Boot
並且您自己沒有任何自定義,例如spring.jpa.open-in-view=false
,那么您是否使用 FetchType.Lazy 來評估equals
應該無關緊要。
首先,建議實施:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return Objects.equals(getIsbn(), book.getIsbn());
}
一旦您開始創建Book
class 的后繼者,就可能違反#equals
方法的symmetric
契約:
其次,延遲加載 ( FetchType.LAZY
) 默認情況下不適用於 HBN 中的 @Basic @Basic
:為了使其工作,您需要啟用字節碼增強功能(IMO,它僅對@Lob
字段有意義)。
並且,第三,使用字段來實現#equals
是不可行的,請考慮以下代碼:
Book ref = session.load(Book.class, id);
Book book = Hibernate.unproxy(ref);
assertThat(book).isEqualTo(ref);
問題是您可能會遇到代理對象( org.hibernate.proxy.HibernateProxy
的實例),它們具有與實體 class 相同的字段,但所有這些字段都是空值:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.