동일성과 동등성
equals()와 hashcode()를 이해하기 전에 먼저 동일성과 동등성에 대한 개념을 짚고 넘어가야 한다.
java의 모든 클래스는 Object클래스를 상속받는데 이 클래스의 멤버 메소드로 equals() 메소드가 있다. equals()메소드는 참조 값(객체 주소 값)이 같은지 확인하는 기능을 한다. 그렇다면 이 메소드는 ==과 무엇이 다를까?
동일성
동일성 비교는 객체 인스턴스의 주소 값을 비교하는 것을 말한다.
동일성 비교시에는 ==을 사용해 비교한다.
primitive data type의 경우 동일성 비교를 통해 값 비교가 가능하다.
동등성
동등성 비교는 객체 내부의 값을 비교하는 것을 말한다.
동등성 비교시에는 equals()메소드를 사용해 비교한다.
주로 primitive data type가 아닌 인스턴스 비교 시에 사용한다.
hashcode
객체 해시코드란 객체를 식별하는 하나의 정수 값이다. Object클래스의 hashCode()는 객체의 메모리 번지를 이용해 해시코드를 만든다.
인스턴스의 동등성 비교시 hashCode()를 오버라이딩 할 필요성이 있다.
컬렉션 프레임워크는 다음과 같은 방법으로 두 객체가 동등한지 비교한다.
- hashCode()를 실행해 해시코드 값이 같은지 비교한다. 다르면 다른 객체로 판단한다.
- equals()메소드로 한번 더 비교한다. 다르면 다른 객체로 판단한다.
위의 두 메소드 실행시 모두 같은 객체로 판단이 돼야 결과적으로 같은 객체라 판단하게 된다.
equals()와 hashCode()를 함께 재정의해야하는 이유
hashCode()를 재정의하지 않았을 때
같은 값의 객체이더라도 리턴되는 해시 값이 다르게 된다. 그렇다면 hash table상에서 해당 객체가 저장된 버킷을 찾을 수 없다.
equals()를 재정의하지 않았을 때
hashCode()메소드를 통해 같은 버킷에 저장된 객체라 판단이 되더라도 해당 객체가 자신과 같은 객체인지 실질적인 값을 비교할 수 없기 때문에 null을 리턴하게 된다. 따라서 비교가 불가능해진다.
위와 같은 이유로 객체의 동등성 비교를 위해서는 equals()메소드와 hashCode() 메소드도 재정의 해주어야 한다.
엔티티의 동등성 비교
영속성 컨텍스트는 엔티티의 식별자를 키로 사용해 엔티티를 관리한다.
이 과정에서 식별자 비교 시 equals()와 hashCode()를 이용해 비교하여 엔티티를 관리하게 된다.
따라서 식별자 객체의 동등성이 지켜지지 않으면 원하는 것과 다른 엔티티가 조회되거나 해당 엔티티를 찾을 수 없는 등 영속성 컨텍스트가 엔티티를 관리하는 과정에 문제가 생긴다.
따라서 복합키를 가진 엔티티는 equals()와 hashCode()를 필수로 구현해야 한다.
참고한 사이트:
엔티티의 동등성
java에서의 동등성
"본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다."
'Spring' 카테고리의 다른 글
@Controller, @RestController 차이 (0) | 2023.02.06 |
---|---|
안전한 Lombok 사용법 (0) | 2023.02.06 |
Spring data JPA: save() 메소드 (0) | 2023.02.06 |
Spring data JPA: 확장 기능 (0) | 2023.02.06 |
Spring data JPA: 쿼리 메소드 (3) (0) | 2023.02.06 |