program tip

JPA 엔티티에 equals () 및 hashCode () 메소드를 작성해야합니까?

radiobox 2020. 12. 14. 08:03
반응형

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 equalshashCode구현을 재정의하지 않는 경우 :

@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.

참고URL : https://stackoverflow.com/questions/4388360/should-i-write-equals-and-hashcode-methods-in-jpa-entities

반응형