- 엔티티의 동등성 비교법
- 비즈니스 키를 사용해
equals()
메서드를 오버라이딩해야함
- 비즈니스 키를 사용해
- 프록시와 동등성 비교 문제
- 단순 원본 엔티티끼리의 비교에서는 IDE 나 외부 라이브러리가 제공한
equals
로 충분하지만..
- 프록시 객체와의 비교에서는 문제가 발생함
- 단순 원본 엔티티끼리의 비교에서는 IDE 나 외부 라이브러리가 제공한
@Entity
public class Member {
@Id
private String id;
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (this.getClass() != obj.getClass()) return false;
Member member = (Member) obj;
if (name != null ? !name.equals(member.name) : member.name != null) return false;
return true;
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
}
- 위 코드를 보면..
일단
프록시 객체와 equals
비교 문제
- JPA 프록시는 원본 엔티티의 대리 객체임.
- 프록시 객체는 원본 엔티티를 상속받아 구현되기에
- getClass() 호출시 메서드가 프록시 클래스를 반환할 수 잇음
- 만약 그렇다면
- 프록시 객체와 원본 엔티티간의 getClass() 의 비교가 실패할 수 있음.
- 이러한 문제 때문에
- equals 메서드를
- JPA 버디에서 제공하는
@Override public final boolean equals(Object o) { if (this == o) return true; if (o == null) return false; Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer() .getPersistentClass() : o.getClass(); Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer() .getPersistentClass() : this.getClass(); if (thisEffectiveClass != oEffectiveClass) return false; Member member = (Member) o; return getId() != null && Objects.equals(getId(), member.getId()); }
- 해당 메서드로 엔티티에서 오버라이딩하여
- 동등성 비교시
Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer() .getPersistentClass() : o.getClass(); Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer() .getPersistentClass() : this.getClass(); if (thisEffectiveClass != oEffectiveClass) return false;
- 현재 객체와 비교하는 객체의 실제 클래스를 확인하고
- 객체가 하이버네이트 구현체의 프록시 객체라면
- 실제 객체를 들고오도록한다.
- 이후 두 실 객체를 비교하도록 하는 방법도 있다.
Uploaded by N2T
'자바 > JPA' 카테고리의 다른 글
[JPA 갑자기 궁금증 해결] DataJpa 에서 save 내부 동작 방식 (0) | 2023.11.19 |
---|---|
[JPA] 영속성 컨텍스트가 다를때의 비교 (0) | 2023.11.19 |
[JPA] 그 유명한 N+1 문제 (0) | 2023.11.19 |
[Jpa] @Convertor 사용 (0) | 2023.11.19 |
[Jpa] 트랜잭션 범위와 영속성 컨텍스트 (0) | 2023.11.17 |