DeveloPiano

[Spring Boot] @EmbeddedId - JPA에서 복합 키를 사용하는 방법 본문

Develop/Spring

[Spring Boot] @EmbeddedId - JPA에서 복합 키를 사용하는 방법

DevPi 2024. 10. 24. 15:30
반응형

데이터베이스 설계에서 때로는 하나의 필드가 아닌 두 개 이상의 필드를 결합하여 기본 키(Primary Key)로 사용해야 할 때가 있습니다. 이런 경우를 복합 키(Composite Key)라고 하며, JPA에서는 이를 지원하기 위해 @EmbeddedId와 @IdClass라는 두 가지 방식을 제공합니다. 이번 포스팅에서는 그중 @EmbeddedId를 사용하여 복합 키를 관리하는 방법에 대해 알아보고, 간단한 예시를 통해 사용법을 소개하겠습니다.


@EmbeddedId란?

@EmbeddedId는 JPA에서 복합 키를 정의할 때 사용하는 어노테이션입니다. 여러 개의 필드를 묶어 하나의 임베디드 객체로 관리하고, 이를 엔티티의 식별자로 사용할 수 있도록 합니다. 이를 통해 복합 키를 객체로 관리할 수 있으며, 객체지향적인 방식으로 데이터를 처리할 수 있습니다.

 

복합 키(Composite Key)란?

복합 키는 두 개 이상의 필드를 결합하여 하나의 식별자로 사용하는 키를 말합니다. 데이터베이스에서 고유하게 식별해야 할 때, 두 개 이상의 컬럼을 결합하여 복합 키로 사용할 수 있습니다. JPA에서는 @EmbeddedId를 통해 이를 쉽게 정의할 수 있습니다.


@EmbeddedId를 사용하는 이유

복합 키가 필요한 상황은 다음과 같습니다.

  • 두 개 이상의 필드를 하나의 식별자로 묶어야 하는 경우
  • 특정 엔티티가 다른 엔티티와 복합 키로 관계를 맺어야 할 때
  • 기존 데이터베이스 구조에서 복합 키를 사용하는 경우

이럴 때 @EmbeddedId를 사용하면 코드가 깔끔해지고 객체지향적인 방식으로 복합 키를 관리할 수 있습니다.


@EmbeddedId 사용 예시

아래 예시에서는 주문(Order)과 관련된 데이터를 관리하는 복합 키를 설정해 보겠습니다. 복합 키는 orderId와 productId라는 두 개의 필드로 구성됩니다.

 

1. 복합 키 클래스 정의하기

복합 키로 사용할 클래스를 먼저 정의해야 합니다. 이 클래스는 반드시 Serializable 인터페이스를 구현해야 하고, equals와 hashCode 메서드를 재정의해야 합니다. 이렇게 정의된 클래스는 @Embeddable 어노테이션으로 선언됩니다.

import java.io.Serializable;
import java.util.Objects;
import jakarta.persistence.Embeddable;

@Embeddable
public class OrderId implements Serializable {

    private Long orderId;
    private Long productId;

    public OrderId() {}

    public OrderId(Long orderId, Long productId) {
        this.orderId = orderId;
        this.productId = productId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        OrderId orderId1 = (OrderId) o;
        return Objects.equals(orderId, orderId1.orderId) &&
               Objects.equals(productId, orderId1.productId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(orderId, productId);
    }
}

 

2. 엔티티 클래스에서 @EmbeddedId 사용하기

이제 OrderId 클래스를 사용하여 Order 엔티티에 복합 키를 설정할 수 있습니다. @EmbeddedId 어노테이션을 사용해 이 클래스를 엔티티의 기본 키로 정의합니다.

import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;

@Entity
public class Order {

    @EmbeddedId
    private OrderId id;

    private String description;

    public Order() {}

    public Order(OrderId id, String description) {
        this.id = id;
        this.description = description;
    }
}

위 예시에서 @EmbeddedId는 OrderId 클래스를 엔티티의 기본 키로 설정하며, orderId와 productId가 결합되어 복합 키를 형성합니다.

 

3. 리포지토리에서 @EmbeddedId 사용하기

복합 키를 사용한 엔티티를 Spring Data JPA에서 다루기 위해서는 리포지토리 인터페이스에서 복합 키를 처리할 수 있어야 합니다. JpaRepository는 기본적으로 이를 지원합니다.

import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, OrderId> {
    // 기본적인 CRUD 메서드 제공
}

 

4. 서비스에서 복합 키 엔티티 사용하기

복합 키를 통해 엔티티를 저장하고 조회하는 방법을 OrderService에서 처리할 수 있습니다. 아래는 복합 키로 엔티티를 저장하고 조회하는 예시입니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

    @Autowired
    private OrderRepository orderRepository;

    public void createOrder(Long orderId, Long productId, String description) {
        OrderId orderKey = new OrderId(orderId, productId);
        Order order = new Order(orderKey, description);
        orderRepository.save(order);
    }

    public Order getOrder(Long orderId, Long productId) {
        OrderId orderKey = new OrderId(orderId, productId);
        return orderRepository.findById(orderKey).orElse(null);
    }
}

위 코드를 통해 복합 키를 사용하여 엔티티를 저장하고, 복합 키로 데이터를 조회하는 방법을 알 수 있습니다.


@EmbeddedId와 @IdClass 비교

JPA에서 복합 키를 정의하는 방법에는 @EmbeddedId와 @IdClass 두 가지가 있습니다. 두 방법 모두 복합 키를 정의할 수 있지만 약간의 차이점이 있습니다.

  • @EmbeddedId는 복합 키를 하나의 객체로 묶어 사용하며, 객체지향적인 방식으로 키를 관리할 수 있습니다.
  • @IdClass는 복합 키 클래스를 별도로 정의하고, 엔티티 클래스에서 필드를 직접적으로 매핑합니다.

 

@EmbeddedId의 장점

  1. 객체지향적 설계: 복합 키를 한 객체로 묶어 관리할 수 있어, 코드가 더 깔끔하고 유지 보수하기 쉽습니다.
  2. 재사용성: 여러 엔티티에서 동일한 복합 키 구조를 재사용할 수 있습니다.
  3. 가독성 향상: 복합 키가 하나의 객체로 관리되기 때문에 코드의 가독성이 높아집니다.

마무리

@EmbeddedId는 JPA에서 복합 키를 처리할 때 매우 유용한 도구입니다. 객체지향적인 방식으로 복합 키를 관리할 수 있으며, 이를 통해 코드의 가독성과 재사용성을 높일 수 있습니다. Spring Data JPA와 쉽게 통합되어 복합 키를 사용하는 엔티티의 CRUD 작업을 간단하게 처리할 수 있습니다.

복잡한 데이터베이스 구조에서도 @EmbeddedId를 잘 활용하면 더욱 직관적이고 유지보수하기 쉬운 코드를 작성할 수 있습니다. 복합 키가 필요한 상황에서는 @EmbeddedId를 활용해 보세요!

반응형