ABOUT

성능과 운영 안정성을 함께 끌어올리는 개발자입니다.

92% Positional Error Reduction
79% p95 Latency Improvement
90%+ Long Tasks Reduction

2022.02 · 한국장학재단

우수 멘티

한국장학재단 사회 리더 대학생 멘토링 IT

2022.10 · 동작구청

우수 인재상

동작구청 우수 SW 인재

2025.05 · (주) 그랩

프로그래밍 우수상

(주) 그랩 우수 프로그램 개발

2025.05 · AWSKRUG

AWS한국사용자모임 발표

AI agent 스크립트 튜닝 관련 발표

ComputerScience

Development

Engineering

Trouble Shooting

GUESTBOOK

첫 마음부터
함께 나누는 온기

방명록 작성하러 가기

SUBSCRIBE

최신소식을
편하게 만나보세요.

동등객체 (Equality Object)

정의

메모리 주소가 달라도, 의미적으로 같은 값/상태를 나타내면 같다고 보는 객체입니다.
백엔드 개발에서 “같다”는 말은 의외로 위험합니다. 같은 사용자인가? 같은 주문인가? 같은 요청인가?
이때 필요한 기준이 동일성(Identity)동등성(Equality)입니다. 그리고 “동등 객체”는 동등성 기준을 명확히 정의한 객체를 의미합니다.

왜 중요한가?
동등성 정의가 흔들리면 Set/Map 중복 처리, 캐시 키 충돌, JPA 엔티티 비교 버그, 테스트 불안정 같은 실무 문제가 터집니다.

1. 동일성(Identity) vs 동등성(Equality)

- 동일성(Identity): “완전히 같은 객체인가?” (같은 인스턴스인가?)
- 동등성(Equality): “값/의미가 같은가?” (다른 인스턴스여도 같다고 볼 수 있는가?)
구분 의미 예시
동일성 같은 참조(주소)의 인스턴스인가 Java에서 ==
동등성 값/의미가 같은가(업무 규칙 기준) Java에서 equals()

2. 백엔드에서 “동등 객체”가 필요한 순간

  • 중복 제거: Set에 담았는데 중복이 안 없어짐(혹은 과도하게 없어짐)
  • 키 조회: HashMap 키로 넣었는데 다시 찾을 수 없음
  • 캐시: 캐시 키/값의 “같음” 기준이 흔들리면 히트율/정확도가 깨짐
  • JPA 엔티티: 동일성/동등성 혼용 시 영속성 컨텍스트와 충돌
  • 테스트: assertThat(a).isEqualTo(b)가 의미대로 동작하지 않음

equals / hashCode 계약(Contract)

equals가 같으면 hashCode도 반드시 같아야 합니다.
Java에서 동등 객체를 제대로 만들려면 equals()hashCode()의 일관성이 핵심입니다.
특히 HashSet / HashMap은 hashCode로 “버킷”을 찾고, equals로 “최종 동등성”을 확인합니다.

필수 규칙
1) a.equals(b) == true 이면 a.hashCode() == b.hashCode() 이어야 한다
2) equals는 반사성/대칭성/추이성/일관성을 만족해야 한다
3) equals에 사용한 필드는 hashCode에도 동일하게 반영해야 한다

3. 동등성 기준 설계: “무엇을 기준으로 같다고 할까?”

동등 객체 설계의 핵심은 결국 도메인 규칙입니다. 아래처럼 기준이 달라질 수 있습니다.
대상 동등성 기준(예) 주의점
Value Object 모든 값(필드) 기반 불변(immutable) 설계가 유리
Entity 식별자(ID) 기반 영속화 전(아이디 없음) 케이스 주의
DTO/Request 요청 의미 기준(필드 일부) 민감정보/시간 필드 포함 여부 신중

4. 실무에서 자주 터지는 함정 5가지

  • mutable 필드를 equals/hashCode에 포함 → Set/Map에 넣은 뒤 값이 바뀌면 “찾을 수 없는 키”가 됨
  • 엔티티의 ID 기반 equals인데 “영속화 전”에는 ID가 없음 → equals가 흔들림
  • 프록시(JPA Proxy) 때문에 클래스 비교 방식(getClass) 선택을 잘못함
  • 시간/랜덤/요청ID 같은 변동 필드를 포함해 “동등성”이 매번 달라짐
  • 캐시 키에 equals/hashCode가 불안정한 객체를 사용 → 캐시 히트율/정확도 붕괴

"동등 객체를 잘 만든다는 것은, ‘무엇이 같은가’를 코드에 명시하는 일입니다."
단순한 유틸 구현이 아니라, 도메인 규칙을 안정적으로 고정하는 설계입니다.

백엔드 실전 가이드

“값 객체는 전체 값 기반”, “엔티티는 식별자 기반”을 기본 원칙으로 잡습니다.
  • Value Object는 가능하면 불변(immutable)으로 만들고, 필드 기반 equals/hashCode
  • Entity는 기본적으로 ID 기반(단, 영속화 전 ID 없음 케이스 설계 필요)
  • HashMap/HashSet 키로는 “변하지 않는 기준”만 사용
  • 캐시 키는 문자열/프리미티브/불변 VO 등 안정적인 형태 권장
728x90