일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- KotlinInAction
- kotlin in action 정리
- Kotlin in action 10장
- 코틀린인액션
- 싱글톤 컨테이너
- 코틸린인액션
- 백준
- 스프링 컨테이너와 스프링 빈
- 20055
- 백준 20055 컨베이어 벨트 위의 로봇
- 백준 13460 Python
- Kotlin in action 6장
- Kotlin in action 5장
- 객체 지향 설계와 스프링
- 스프링 핵심 원리 이해
- 코틀린
- 스프링 핵심 원리
- Kotlin
- 20055 컨베이어 벨트 위의 로봇
- Kotlin In Action
- spring
- Kotlin in action 3장
- 7장 고급매핑
- Python
- 컨베이어 벨트 위의 로봇 Python
- 스프링 핵심 원리 - 기본편
- 기능개발 python
- 고급매핑
- 13460 구슬탈출 2
- 자바 ORM 표준 JPA 프로그래밍 7장
- Today
- Total
기록하는 습관
[JPA] 복합키에서 equals () 및 hashCode () 구현 본문
회사에서 JPA 스터디를 중간에 참여하게 되어 7장부터 글을 쓰게 되었다.
앞으로 책을 읽고 알게된 내용이나, 궁금했던 점 위주로 정리할 예정이다.
복합 키와 식별관계 매핑
식별관계 vs 비식별관계
DB 테이블 사이의 관계는 외래 키가 기본 키에 포함되는지 여부에 따라 식별, 비식별로 구분된다.
식별관계
식별 관계는 부모 테이블의 기본 키를 내려 받아 자식 테이블의 기본키 + 외래키로 사용하는 관계
비식별관계
비식별 관계는 부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계다.
비식별 관계는 외래키에 NULL을 허용하는지에 따라 필수적, 선택적으로 갈린다.
- 필수적 비식별 관계
- 외래키에 NULL 허용하지 않음
- 연관관계를 필수적으로 맺어야함
- 선택적 비식별 관계
- 외래키에 NULL 허용함
- 연관관계를 맺을지 말지 선택 가능
** 비식별 관계를 주로 사용하는 것을 추천한다.
복합키를 구성하기 위한 필수조건
1. @EmbeddedId 또는 @IdClass
2. public의 no-args constructor
3. serializable을 상속 받기
4. equals(), hashCode() Override
복합키 : 비식별 관계 매핑
식별자 필드가 2개 이상이면 별도의 식별자 클래스를 만들고 equals와 hashcode를 override해야 한다.
JPA는 복합키를 지원하기 위해 @IdClass, @EmbeddedId 2가지 방법을 제공한다.
@IdClass는 관계형 DB에 가까운 방법이고 @EmbeddedId는 좀 더 객체지향에 가까운 방법이다.
ParentId id1 = new ParentId();
id1.setId1("test1");
id1.setId2("test2");
ParentId id2 = new ParentId();
id2.setId1("test1");
id2.setId2("test2");
id1.equals(id2) // false
id1.equals(id2) 의 결과값은 false이다.
자바의 모든 클래스는 기본으로 Object 클래스를 상속받는데 이 클래스가 제공하는 기본 equals()는 인스턴스 참조 값 비교인 ==비교(동일성비교)를 하기 때문이다.
식별자 클래스의 equals(), hashCode()는 영속성 컨텍스트가 식별자를 비교할때 사용하기 때문에 반드시 오버라이딩 해야한다.
식별자 객체의 동등성(equals)이 지켜지지 않으면 예상과 다른 엔티티가 조회되거나 엔티티를 찾을 수 없는 등 영속성 컨텍스트가 엔티티를 관리하는 데 문제가 발생한다.
복합 키를 사용할 때 equals()와 hashCode()를 필수로 구현해야 하는 이유?
복합키는 일반적으로 두 개 이상의 필드를 조합하여 하나의 키를 구성하는데, 여러 필드로 구성된 복합키의 경우에는 각 필드의 값이 같더라도 인스턴스가 다를 수 있다. 이때 equals()와 hashCode() 메서드를 적절히 오버라이딩하여 두 객체가 동일한 키를 나타내는지를 정의하면, 해시 기반의 자료구조에서 올바르게 동작하도록 할 수 있다.
equals() 메서드를 오버라이딩하는 이유:
- equals() 메서드는 두 객체가 동등한지 여부를 판단한다. 복합키의 경우, 여러 필드를 비교하여 동등성을 판단해야 한다. 따라서 equals() 메서드를 오버라이딩하여 동등성 비교를 정의할 수 있다.
hashCode() 메서드를 오버라이딩하는 이유:
- hashCode() 메서드는 해시 기반 자료구조에서 객체의 해시 코드를 반환한다. 해시 기반 자료구조에서 객체를 저장하고 검색할 때 해시 코드를 사용하여 성능을 향상시킬 수 있다. 복합키의 경우, 각 필드의 해시 코드를 조합하여 객체의 해시 코드를 생성할 수 있도록 hashCode() 메서드를 오버라이딩해야 한다.
equals()와 hashCode()를 오버라이딩 하는 예시
OrderKey 클래스가 있고, 사용자 ID와 주문 번호 두 필드로 구성되어 있다.
각 주문은 사용자 ID와 주문 번호로 식별된다. (= 복합키)
import java.util.Objects;
public class OrderKey {
private Long userId;
private String orderNumber;
// 생성자, getter, setter 생략 (필요에 따라 구현)
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrderKey orderKey = (OrderKey) o;
return Objects.equals(userId, orderKey.userId) &&
Objects.equals(orderNumber, orderKey.orderNumber);
}
@Override
public int hashCode() {
return Objects.hash(userId, orderNumber);
}
}
위 코드에서는 OrderKey 클래스를 정의하고, 이 클래스에서 equals()와 hashCode() 메서드를 오버라이딩하여 복합키의 동등성 비교와 해시 코드 생성을 정의했다.
'스터디 > 자바 ORM 표준 JPA 프로그래밍' 카테고리의 다른 글
[JPA] 예외 처리와 엔티티 비교 (1) | 2024.01.25 |
---|---|
[JPA] 스프링 데이터 JPA (2) (0) | 2023.12.14 |
[JPA] 객체지향 쿼리와 JPQL (1) | 2023.11.09 |
[JPA] 9장 값 타입 (0) | 2023.10.25 |