programing

JPA 및 휴지 상태 사용 시 동일 및 해시 코드 구현 방법

projobs 2022. 9. 25. 11:17
반응형

JPA 및 휴지 상태 사용 시 동일 및 해시 코드 구현 방법

Hibernate에서 모델 클래스의 등가 및 해시 코드를 구현하는 방법을 선택하십시오.일반적인 함정은 무엇입니까?대부분의 경우 기본 구현으로 충분합니까?비즈니스 키를 사용하는 센스가 있습니까?

게으른 페치, ID 생성, 프록시 등을 고려할 때 모든 상황에서 제대로 작동시키기는 어려울 것 같습니다.

에는 언제,되어 있습니다.equals()hashCode()문서화해서

는 만약 의 실체가 그 실체가 그 실체에 만 하면 이다.Set또는 인스턴스를 분리/연결할 것인지 확인합니다.후자는 그렇게 흔하지 않다.전자는 일반적으로 다음을 통해 처리하는 것이 가장 좋습니다.

  1. ★★★equals()hashCode()비즈니스 키 - 예를 들어 객체(또는 적어도 세션) 수명 동안 변경되지 않는 고유한 속성 조합입니다.
  2. 는, 베이스 「」를 참조해 .equals()hashCode() itidentity / on on on on on on가가가가ID /System.identityHashCode()그렇지않으면.여기서 중요한 것은 새 엔티티가 추가되고 지속된 후 세트를 새로고침해야 한다는 것입니다. 그렇지 않으면 현재와 일치하지 않는 버킷에 엔티티가 할당될 수 있기 때문에 이상한 동작이 발생할 수 있습니다(결국 오류 및/또는 데이터 파손이 발생할 수 있습니다.hashCode().

나는 인정된 답이 정확하다고 생각하지 않는다.

원래 질문에 답하려면:

대부분의 경우 기본 구현으로 충분합니까?

대답은 '그렇다'입니다.대부분 그렇습니다.

은 어어기 need you어 you you you you 。equals() ★★★★★★★★★★★★★★★★★」hashcode()가 "에서 Set(매우 일반적인) 엔티티가 휴지 상태 세션에서 분리되었다가 다시 접속됩니다(이것은 휴지 상태의 일반적인 사용법입니다).

수락된 답변은 어느 하나의 조건이 참일 경우 메서드를 덮어쓸 필요가 있음을 나타냅니다.

★★★★★★equals ★★★★★★★★★★★★★★★★★」hashCode구현은 다음과 같이 고유한 비즈니스 키 또는 자연 식별자를 사용하는 경우입니다.

@Entity
public class Company {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
 
    @Column(unique = true, updatable = false)
    private String name;
 
    @Override
    public int hashCode() {
        HashCodeBuilder hcb = new HashCodeBuilder();
        hcb.append(name);
        return hcb.toHashCode();
    }
 
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Company)) {
            return false;
        }
        Company that = (Company) obj;
        EqualsBuilder eb = new EqualsBuilder();
        eb.append(name, that.name);
        return eb.isEquals();
    }
}

비즈니스 키는 모든 엔티티 상태 전환(과도적, 연결됨, 분리됨, 제거됨)에 걸쳐 일관성이 있어야 하므로 ID에 의존하여 동등성을 유지할 수 없습니다.

다른 옵션은 애플리케이션 로직에 의해 할당된 UUID 식별자를 사용하는 것으로 전환하는 것입니다.하면 를 UUID에 할 수 .equals/hashCode엔티티가 플러시되기 전에 ID가 할당되기 때문입니다.

는 엔티티 식별자도 할 수 .equals ★★★★★★★★★★★★★★★★★」hashCode[아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아hashCode엔티티 hashCode 값이 다음과 같이 모든 엔티티 상태 천이 간에 일관되도록 합니다.

@Entity(name = "Post")
@Table(name = "post")
public class Post implements Identifiable<Long> {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    public Post() {}
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
 
        if (!(o instanceof Post))
            return false;
 
        Post other = (Post) o;
 
        return id != null &&
               id.equals(other.getId());
    }
 
    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
  
    //Getters and setters omitted for brevity
}

엔티티가 느린 로딩으로 로드되면 기본 유형의 인스턴스가 아니라 javassist에 의해 동적으로 생성된 하위 유형이므로 동일한 클래스 유형에 대한 검사가 실패하므로 다음을 사용하지 마십시오.

if (getClass() != that.getClass()) return false;

대신 다음을 사용합니다.

if (!(otherObject instanceof Unit)) return false;

이는 Java Practices의 "Implementing equals"에서 설명한 바와 같이 좋은 프랙티스이기도 합니다.

같은 이유로 필드에 직접 액세스하면 기본값이 아닌 null이 반환될 수 있으므로 속성 비교를 사용하지 말고 getters를 사용하여 기본값을 로드하는 경우가 있습니다.

네, 어려워요.내 프로젝트에서는 hashCode와 동등하며 둘 다 객체의 ID에 의존합니다.이 솔루션의 문제는 ID가 데이터베이스에 의해 생성되므로 개체가 아직 유지되지 않은 경우 둘 다 작동하지 않는다는 것입니다.내 경우 대부분의 경우 개체가 즉시 유지되기 때문에 이 정도는 견딜 수 있습니다.그 이외에는, 동작도 훌륭하고, 실장도 간단합니다.

「Hibernate 5.2」의 메뉴얼에는, 상황에 따라서는, 해시 코드를 실장하고 싶지 않을 가능성이 있어, 동등하다고 기재되어 있습니다.

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#mapping-model-pojo-equalshashcode

일반적으로 (hashCode 및 equals를 구현하지 않으면) 같은 세션에서 로드된2개의 오브젝트가 데이터베이스 내에서 동일할 경우 동일합니다.

두 개 이상의 세션을 사용하는 경우 복잡해집니다.이 경우 두 개체의 동일성은 동등한 방식의 구현에 따라 달라집니다.

또한 Equals-Method가 오브젝트를 처음 유지할 때만 생성되는 ID를 비교하고 있으면 문제가 발생합니다.평등이 호출될 때 그들은 아직 그곳에 없을지도 모른다.

여기 아주 좋은 기사가 있습니다: https://docs.jboss.org/hibernate/stable/core.old/reference/en/html/persistent-classes-equalshashcode.html

기사의 중요한 한 줄을 인용합니다.

비즈니스 키의 이퀄리티를 사용하여 equals()와 hashCode()를 구현할 것을 권장합니다.비즈니스 키의 동등성은 equals() 메서드가 비즈니스 키를 형성하는 속성만 비교하는 것을 의미합니다.이 키는 실제 세계에서 우리의 인스턴스를 식별하는 키(자연 후보 키)입니다.

간단히 말하면

public class Cat {

...
public boolean equals(Object other) {
    //Basic test / class cast
    return this.catId==other.catId;
}

public int hashCode() {
    int result;

    return 3*this.catId; //any primenumber 
}

}

만약 당신이 우연히 재지정하게 된다면equals계약을 이행해 주세요.-

  • 대칭
  • 사색적인
  • 전이적
  • 일관된
  • 비특수

오버라이드hashCode계약에 의존하기 때문에equals실행.

Joshua Bloch(컬렉션 프레임워크 설계자)는 이러한 규칙을 따를 것을 강력히 촉구했다.

  • 항목 9: 동일 항목을 재정의할 때 항상 hashCode를 재정의합니다.

이 계약서를 따르지 않을 경우 의도하지 않은 심각한 영향이 있습니다.예를들면List#contains(Object o)잘못 반환될 수 있음boolean일반계약이 이행되지 않은 경우의 가치.

언급URL : https://stackoverflow.com/questions/1638723/how-should-equals-and-hashcode-be-implemented-when-using-jpa-and-hibernate

반응형