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

2022.02 · 한국장학재단

우수 멘티

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

2022.10 · 동작구청

우수 인재상

동작구청 우수 SW 인재

2025.05 · (주) 그랩

프로그래밍 우수상

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

2025.05 · AWSKRUG

AWS한국사용자모임 발표

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

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

방명록 작성하러 가기

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

동등객체 (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