JPA

[JPA] 값 타입 비교

째로스 2023. 7. 21. 13:06

목표

인스턴스가 달라도 그 안의 값이 같으면 같은 것으로 볼 수 있게한다.

(특히 참조 객체에서)

 

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가 반환된다.