エンティティがコレクションメンバーにあるかどうかを確認したい(@OneToMany
または@ManyToMany
)別のエンティティ:
if (entity2.getEntities1().contains(entity1)) { }
必ずしも。次の3つのオプションがあります。
オーバーライドしないでください-したがって、インスタンスを操作します。これは、セッションにアタッチされているエンティティのみでコレクションを操作している場合(したがって、同じインスタンスであることが保証されている場合)には問題ありません。多くの場合、これは(私にとって)好ましい方法です。オーバーライドする際に必要なコードと考慮事項が少ないためです。
hashCode()
およびequals()
をビジネスキーでオーバーライドします。それは、エンティティを識別するプロパティのサブセットである場合があります。たとえば、User
の場合、適切なビジネスキーはusername
またはemail
です。これは良い習慣と見なされます。
iDフィールドのみを使用して、hashCode()
およびequals()
をオーバーライドします。これは、特に手動で割り当てられた識別子(UUIDなど)がある場合は特に問題ありません。エンティティがコレクションに決して入らない場合も問題ありません。ただし、コレクションに入る一時的なエンティティ(識別子なし)の場合、問題が発生するため、このオプションには注意が必要です。 seanizerが指摘したように-あなたはそれを避けるべきです。一般的に、常に、あなたが何をしているのかを本当に知っていない限り(そして、おそらくそれを文書化する)
この記事を参照 詳細については。また、equals()
とhashCode()
は結び付けられており、両方ともまったく同じフィールドで実装する必要があることに注意してください。
はい、そうすべきです!
デフォルトのJava.lang.Object
equals
およびhashCode
実装をオーバーライドしない場合:
@Entity(name = "Book")
public class Book implements Identifiable<Long> {
@Id
@GeneratedValue
private Long id;
private String title;
//Getters and setters omitted for brevity
}
merge
操作は異なるオブジェクトインスタンスを返し、等式コントラクトは壊れます この投稿で説明するように 。
最善の方法は、次のようにビジネスキーを使用することです。
@Entity
public class Book implements Identifiable<Long> {
@Id
@GeneratedValue
private Long id;
private String title;
@NaturalId
private String isbn;
@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 int hashCode() {
return Objects.hash(getIsbn());
}
//Getters and setters omitted for brevity
}
識別子を平等に使用することもできますが、hashCodeの実装は、すでに説明した同じ投稿で説明されているように、常に同じ値を返す必要があることに注意してください。
@Entity
public class Book implements Identifiable<Long> {
@Id
@GeneratedValue
private Long id;
private String title;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Book)) return false;
Book book = (Book) o;
return Objects.equals(getId(), book.getId());
}
@Override
public int hashCode() {
return 31;
}
//Getters and setters omitted for brevity
}
はい、対応するequals()
およびhashcode()
メソッドを定義する必要がありますが、idをいずれかの一部にしないでください。 (同様の質問の 私の最近の回答 を参照)
IDE generate hashCode()
およびequals()
を生成する傾向があります。ただし、注意してください。JPAエンティティ用のこれらのメソッドを生成するとき。equals()
クラスアイデンティティのチェック
// ... inside equals() - wrong approach for Entities (cause of generate proxies)
if (o == null || this.getClass() != o.getClass()) {
return false;
}
// ...
これらのライブラリは、たとえばHibernateのMyGreatEntity_$$_javassist_7
のように、エンティティ(サブクラス)のプロキシを作成するため、一部のJPAライブラリを使用するとコレクションが破損します。
エンティティでは、equals()
のサブクラスを常に許可します。
それが唯一の方法です。 Pojomatic ライブラリを試してみるとよいでしょう。