일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 1차원 DP
- 2차원 dp
- 99클럽
- @BeforeAll
- @BeforeEach
- @Builder
- @Entity
- @GeneratedValue
- @GenericGenerator
- @NoargsConstructor
- @Query
- @Table
- @Transactional
- Actions
- Amazon EFS
- amazon fsx
- Android Studio
- ANSI SQL
- ApplicationEvent
- assertThat
- async/await
- AVG
- AWS
- Azure
- bind
- builder
- button
- c++
- c++ builder
- c03
- Today
- Total
기록
[자바 ORM 표준 JPA 프로그래밍] JPA 복합 키 매핑: @IdClass vs @EmbeddedId, 조인컬럼과 조인테이블 (7장-2) 본문
[자바 ORM 표준 JPA 프로그래밍] JPA 복합 키 매핑: @IdClass vs @EmbeddedId, 조인컬럼과 조인테이블 (7장-2)
youngyin 2024. 12. 1. 10:00시작하면서
아래는 "자바 ORM 표준 JPA 기술"의 7장 내용을 읽고 정리한 내용입니다. 복합 키와 식별 관계 매핑은 JPA에서 엔티티 설계 시 가장 중요한 고려사항 중 하나입니다. 데이터베이스의 구조와 비즈니스 로직의 유연성을 결정하는데 큰 영향을 미치기 때문입니다. 이 포스트에서는 JPA의 복합 키 매핑 방식인 @IdClass
와 @EmbeddedId
를 비교하고, 이를 통해 식별 관계와 비식별 관계를 어떻게 설계할 수 있는지 설명하겠습니다.
1. 식별 관계와 비식별 관계 개요
복합 키를 사용할 때에는 '식별 관계'와 '비식별 관계' 중 어떤 것을 선택할 것인지에 대한 고민이 필요합니다. 이 두 관계는 외래 키가 기본 키에 포함되는지 여부에 따라 구분됩니다. 최근에는 비식별 관계가 더 많이 사용되며 권장되는 방식입니다. 이를 통해 각 엔티티의 독립성을 보장하고 관리의 유연성을 높일 수 있기 때문입니다.
1.1 식별 관계 정의 및 예시
식별 관계란 외래 키가 기본 키에 포함되는 경우를 의미합니다. 이러한 설계 방식에서는 부모 엔티티와 자식 엔티티 간의 강한 종속성이 존재하며, 이는 데이터 모델링을 매우 엄격하게 만듭니다.
예를 들어, **주문(Order)**과 주문 항목(OrderItem) 간의 관계에서, 주문 항목이 주문의 기본 키를 포함하고 있다면, 이는 식별 관계입니다. 즉, 주문(Order)이 삭제되면 주문 항목(OrderItem)도 함께 삭제되어야 합니다.
테이블 예시:
테이블명 | 컬럼명 | 설명 |
---|---|---|
Order | order_id (PK) | 주문의 기본 키 |
order_date | 주문 날짜 | |
OrderItem | order_id (PK, FK) | 주문의 기본 키, 외래 키 |
item_id (PK) | 주문 항목의 기본 키 | |
quantity | 주문 항목의 수량 |
1.2 비식별 관계 정의 및 예시
비식별 관계는 외래 키가 기본 키에 포함되지 않고 별도로 관리되는 경우를 의미합니다. 이 방식에서는 각 엔티티가 독립적으로 관리되며, 기본 키로 **Long 타입의 대리 키(surrogate key)**를 사용하는 것이 일반적입니다. 이를 통해 엔티티 간의 종속성을 줄이고 변경에 대한 유연성을 높일 수 있습니다.
예를 들어, **회원(Member)**과 주문(Order) 간의 관계에서, 주문(Order)은 회원(Member)의 외래 키를 포함하지만, 이 외래 키는 주문 테이블의 기본 키에 포함되지 않습니다.
테이블 예시:
테이블명 | 컬럼명 | 설명 |
---|---|---|
Member | member_id (PK) | 회원의 기본 키 |
name | 회원 이름 | |
Order | order_id (PK) | 주문의 기본 키 |
member_id (FK) | 회원의 외래 키 | |
order_date | 주문 날짜 |
비식별 관계를 활용하면 각 엔티티가 대리 키를 통해 독립적으로 존재할 수 있어, 엔티티의 수명 주기를 더 쉽게 관리할 수 있습니다.
2. JPA 복합 키 매핑 방식 비교
JPA는 복합 키를 매핑하는 두 가지 방법을 지원합니다: @IdClass
와 @EmbeddedId
입니다. 두 방법 모두 장단점이 있으며, 어떤 방식을 사용할지는 상황에 따라 달라질 수 있습니다.
2.1 @IdClass 방식 개요 및 사용 예시
@IdClass
는 관계형 데이터베이스의 전통적인 방식을 따르며, 별도의 식별자 클래스를 만들어 기본 키를 정의합니다. 아래는 예시 코드입니다:
import java.io.Serializable;
public class OrderItemId implements Serializable {
private Long orderId;
private Long itemId;
// 기본 생성자, equals, hashCode 구현 필요
}
@Entity
@IdClass(OrderItemId.class)
public class OrderItem {
@Id
private Long orderId;
@Id
private Long itemId;
private int quantity;
// getter, setter 등
}
이 방식은 데이터베이스와의 명확한 매핑을 위해 적합하며, 관계형 데이터베이스의 복합 키 구조를 그대로 반영합니다.
2.2 @EmbeddedId 방식 개요 및 사용 예시
@EmbeddedId
는 객체 지향적인 방식으로, 복합 키를 임베디드 객체로 관리합니다. 코드의 가독성과 재사용성을 높이는 데 유리하며, 아래와 같은 예시로 구현할 수 있습니다:
@Embeddable
public class OrderId implements Serializable {
private Long orderId;
private Long productId;
// equals, hashCode 구현 필요
}
@Entity
public class Order {
@EmbeddedId
private OrderId id;
// 기타 속성들
}
@EmbeddedId
를 사용하면 복합 키를 하나의 객체로 다룰 수 있어 엔티티의 속성을 좀 더 직관적이고 명확하게 표현할 수 있습니다.
2.3 @IdClass vs @EmbeddedId: 선택 기준
@IdClass
와 @EmbeddedId
중 어느 것을 선택할지는 설계의 목적과 사용 편의성에 따라 달라집니다. 복합 키의 구조가 간단하고 엔티티에서 직접 다루는 것이 더 직관적일 때는 @EmbeddedId
를, 데이터베이스의 관계 매핑이 더 중요할 때는 @IdClass
를 사용하는 것이 좋습니다.
3. JPA 조인 테이블 사용 전략
JPA에서는 엔티티 간의 관계를 정의할 때 조인 컬럼이나 조인 테이블을 사용할 수 있습니다.
3.1 조인 컬럼과 조인 테이블의 선택 기준
관계가 단순하고 외래 키를 통해 충분히 관리가 가능한 경우에는 조인 컬럼을, 관계가 복잡하거나 다대다 매핑이 필요한 경우에는 조인 테이블을 사용하는 것이 좋습니다.
3.2 일대일 관계에서 조인 테이블 매핑
일대일 관계에서 조인 테이블을 사용하는 경우, @JoinTable
어노테이션을 사용하여 두 엔티티 간의 관계를 정의할 수 있습니다. 예를 들어, 회원(Member)과 회원 상세 정보(MemberDetail) 간의 일대일 관계를 조인 테이블을 통해 매핑할 수 있습니다.
@Entity
public class Member {
@Id
private Long memberId;
@OneToOne
@JoinTable(name = "member_detail_join",
joinColumns = @JoinColumn(name = "member_id"),
inverseJoinColumns = @JoinColumn(name = "detail_id"))
private MemberDetail memberDetail;
}
3.3 일대다 관계에서 조인 테이블 매핑
일대다 관계에서는 보통 조인 컬럼을 사용하지만, 조인 테이블을 활용할 수도 있습니다. 예를 들어, **부모(Parent)**와 여러 자식(Child) 간의 일대다 관계를 조인 테이블로 매핑할 수 있습니다.
@Entity
public class Parent {
@Id
private Long parentId;
@OneToMany
@JoinTable(name = "parent_child_join",
joinColumns = @JoinColumn(name = "parent_id"),
inverseJoinColumns = @JoinColumn(name = "child_id"))
private List<Child> children;
}
3.4 다대다 관계에서 조인 테이블 매핑
다대다 관계에서는 조인 테이블을 사용하는 것이 일반적이며, 이를 통해 두 엔티티 간의 관계를 관리합니다. 예를 들어, **학생(Student)**과 수업(Course) 간의 다대다 관계를 매핑할 때 조인 테이블을 사용할 수 있습니다.
@Entity
public class Student {
@Id
private Long studentId;
@ManyToMany
@JoinTable(name = "student_course_join",
joinColumns = @JoinColumn(name = "student_id"),
inverseJoinColumns = @JoinColumn(name = "course_id"))
private List<Course> courses;
}
@Entity
public class Course {
@Id
private Long courseId;
@ManyToMany(mappedBy = "courses")
private List<Student> students;
}
예를 들어, 일대일 관계에서 조인 테이블을 사용할 때는 @JoinTable
어노테이션을 사용하여 관계를 매핑할 수 있습니다.
4. 엔티티와 다중 테이블 매핑 전략
하나의 엔티티가 여러 테이블과 매핑되어야 하는 경우도 있습니다. 이때 @SecondaryTable
을 사용할 수 있지만, 일반적으로 권장되지 않습니다. 각각의 테이블에 별도 엔티티를 매핑하고, 엔티티 간 일대일 관계를 사용하는 것이 더 유연하고 유지보수에도 유리합니다.
5. 결론 및 권장 사항
JPA에서 복합 키와 식별 관계를 매핑하는 것은 설계의 중요한 결정 요소입니다. @IdClass
와 @EmbeddedId
는 각각 장단점이 있기 때문에, 애플리케이션의 요구 사항과 데이터베이스 구조에 맞는 방법을 선택해야 합니다. 특히, 현대적인 데이터베이스 설계에서는 식별 관계보다는 비식별 관계를 통해 각 엔티티의 독립성을 보장하고, 변경에 대한 유연성을 높이는 방식이 더 선호됩니다.
'교육 > 책' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] JPA 값 타입 - 기본 값 타입, 임베디드 타입, 값 타입 컬렉션 (9장) (0) | 2024.12.01 |
---|---|
[자바 ORM 표준 JPA 프로그래밍] JPA의 프록시와 연관관계 관리: 지연 로딩, 영속성 전이, 고아 객체 (8장) (0) | 2024.12.01 |
[자바 ORM 표준 JPA 프로그래밍] JPA 고급 매핑: 상속 관계 매핑(7장-1) (0) | 2024.12.01 |
[자바 ORM 표준 JPA 프로그래밍] 다양한 연관관계 매핑: 일대다, 다대일, 다대다 (6장) (0) | 2024.11.27 |
[자바 ORM 표준 JPA 프로그래밍] JPA 연관관계 매핑 기초: 단방향과 양방향 연관관계 (5장) (0) | 2024.11.23 |