簡體   English   中英

我應該在 JPA 實體等於方法中使用 getter 還是字段?

[英]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契約:

  • 對於任何非空引用值 x 和 y,x.equals(y) 應該返回 true 當且僅當 y.equals(x) 返回 true。

其次,延遲加載 ( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM