JPA 엔티티에 equals () 및 hashCode () 메소드를 작성해야합니까?
엔터티가 다른 엔터티 의 컬렉션 구성원 ( @OneToMany
또는 @ManyToMany
)에 있는지 확인하고 싶습니다 .
if (entity2.getEntities1().contains(entity1)) { }
반드시 그런 것은 아닙니다. 세 가지 옵션이 있습니다.
재정의하지 마십시오. 따라서 인스턴스로 작업하게됩니다. 세션에 연결된 엔티티 만있는 컬렉션으로 작업하는 경우에는 괜찮습니다 (따라서 동일한 인스턴스가 보장됨). 이것은 재정의 할 때 코드와 고려 사항이 적기 때문에 많은 경우에 선호되는 방법입니다.
재정의
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가 어느 쪽에도 포함되지 않도록해야합니다. ( 비슷한 질문에서 내 최근 답변 참조 )
이 주제에 대한 Hibernate 문서에 정보가 있습니다.
We tend to let IDE generate hashCode()
and equals()
for us. Be careful though. When you generate those methods for JPA Entities. Some versions of equals()
checks for class identity
// ... inside equals() - wrong approach for Entities (cause of generate proxies)
if (o == null || this.getClass() != o.getClass()) {
return false;
}
// ...
This would break your collections with some JPA libraries as those libraries create proxies to your entities (subclasses), like for example MyGreatEntity_$$_javassist_7
in Hibernate.
In Entities always allow subclasses in equals()
.
That's the only way. You may want to try Pojomatic library which does the hard job for you.
'program tip' 카테고리의 다른 글
JavaScript에서 새로 추가 된 요소에 onclick 이벤트 추가 (0) | 2020.12.14 |
---|---|
jQuery, .each를 사용하여 클래스의 각 요소 ID를 얻습니까? (0) | 2020.12.14 |
f.select 양식 필드에 공백 값을 설정하는 방법 (0) | 2020.12.14 |
각 그룹 내에서 지연 변수를 만드는 방법은 무엇입니까? (0) | 2020.12.14 |
ADB를 통해 연결된 기기의 Android OS 버전 가져 오기 (0) | 2020.12.14 |