목표
인스턴스가 달라도 그 안의 값이 같으면 같은 것으로 볼 수 있게한다.
(특히 참조 객체에서)
int a = 5;
int b = 5;
System.out.println("a==b : " + (a==b)); // true
City city1 = new City("Seoul", "street", "10000");
City city2 = new City("Seoul", "street", "10000");
System.out.println("city1==city2 : " + (city1==city2)); // false
System.out.println("city1==city2 : " + (city1.equals(city2))); // false
값 타입 비교
1) 동일성(identity) 비교 : 인스턴스의 참조 값을 비교, ==사용
2) 동등성(equivalence) 비교 : 인스턴스의 값을 비교, equals() 사용
- 값 타입은 equals를 사용해서 동등성 비교를 해야하는데, 객체의 필드가 많으면 메소드를 적절하게 재저으히 해줘야한다.
(위에서도 equals를 썻지만, 객체 내부의 모든 필드를 비교하도록 재정의 해주지 않았기 때문에 false가 나온것이다.)
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return Objects.equals(getCity(), address.getCity()) &&
Objects.equals(getStreet(), address.getStreet()) &&
Objects.equals(getZipcode(), address.getZipcode());
}
@Override
public int hashCode() {
return Objects.hash(city, street, zipcode);
}
}
getter를 사용하여 필드들을 비교해주는 것이 바람직하다.
왜냐하면 프록시로 접근할 경우, getter를 사용하여 엔티티 메소드로 접근하지 않는 경우
필드 값을 제대로 읽지 못할 수 있기 때문이다.
프록시가 아니더라도 객체지향에서는 getter로 필드 값을 읽어가는 것이 안전하다.
(Intelij에서는 마우스 우클릭 후 Generate에서 자동으로 재정의 메소드를 생성할 수 있다.)
City city1 = new City("Seoul", "street", "10000");
City city2 = new City("Seoul", "street", "10000");
System.out.println("city1==city2 : " + (city1==city2)); // false
System.out.println("city1==city2 : " + (city1.equals(city2))); // true
위와 같이 equals를 재정의하고 다시 실행시키면 true가 반환된다.
'JPA' 카테고리의 다른 글
[JPA] 값 타입 컬렉션 (0) | 2023.07.21 |
---|---|
[JPA] 값 타입과 불변 객체 (0) | 2023.07.21 |
[JPA] 임베디드 타입 (0) | 2023.07.21 |
[JPA] 영속성 전이(CASCADE)와 고아 객체 (0) | 2023.07.17 |
[JPA] 프록시와 즉시/지연 로딩 (0) | 2023.07.17 |