엔티티 수정?!

엉금엉금·2022년 6월 28일

해결 중인 문제

목록 보기
3/7

API를 만들기 위한 요구 사항은 다음과 같다
(정말 간단히 작성한다)

  1. 음식점 등록 및 조회
  2. 음식 등록 및 메뉴판 조회
  3. 주문하기

Spring Data JPA를 이용하여 구현하였고 시작할 때에는 요구사항 명세서에 적힌 것을 토대로 즉흥적으로 Entity를 만들었다.

@Entity
public class Restaurant extends Timestamped {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private int minOrderPrice;

    @Column(nullable = false)
    private int deliveryFee;
}

가령 위 코드와 같이 명세서의 음식점이라 하면 음식점 이름, 최소 주문 가격 그리고 기본 배달비의 속성을 있는 그대로 써내려갔다. 이러한 식으로 음식점, 음식, 주문의 Entity가 세상에 나오게 되었다.

  • 기존 주문 엔티티
@Entity
public class Order extends Timestamped {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String orderId;

    @Column(nullable = false)
    private Long restaurantId;

    @Column(nullable = false)
    private Long foodId;

    @Column(nullable = false)
    private Integer quantity;

    public Order(String orderId, Food food, Integer quantity) {
        this.orderId = orderId;
        this.restaurantId = food.getRestaurantId();
        this.foodId = food.getId();
        this.quantity = quantity;
    }
}

그런데 주문에 관한 API 기능을 만들 때 문제가 발생했다. 우선 주문에 관한 명세서 상의 응답은 식당의 이름, 배달비, 주문 총 금액 그리고 주문한 음식에 관한 이름, 수량, 가격에 관한 정보나 그 리스트이다. RDBMS를 사용함에도 불구하고 테이블 간에 관계를 설정하지 않아 각각 테이블에서 원하는 정보를 가져와야 하는 것과 모든 주문에 관한 정보를 응답의 로직이 복잡한 것이 문제였다.

  • 수정 주문 엔티티
@Entity
public class Order extends Timestamped {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ORDER_ID")
    private Long id;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name = "RESTAURANT_ID")
    private Restaurant restaurant;

    @OneToMany(fetch = LAZY, mappedBy = "order")
    List<OrderFood> OrderFoods = new ArrayList<>();
    
    ...
}

우선 첫번째 문제는 데이터 베이스의 테이블 간의 관계에 대해서 정의를 해본 후 PK, FK를 설정하는 것으로 해결했다. 이를 @ManyToOne, @OneToMany 그리고 @JoinColumn 어노테이션을 이용하여 연관관계 매핑을 맺었다. 위 코드는 해당 구현 내용이다.

  • 새로 만든 주문_음식 엔티티
@Entity
public class OrderFood {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ORDER_FOOD_ID")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ORDER_ID")
    private Order order;

    @OneToOne
    @JoinColumn(name = "FOOD_ID")
    private Food food;

    @Column(name = "ORDER_FOOD_QUANTITY", nullable = false)
    private Integer quantity;

    ...
}

두번째 문제는 주문에 관한 Entity을 재정의하고 정규화를 해보는 것으로 시작을 했다. 주문은 기본적으로 시간, 음식점 정보, 음식 종류와 각각의 수량을 필요로 하는데 한 Entity에 이를 모두 담으면 같은 정보를 여러 컬럼에서 갖게 되는 일이 발생하기 때문에 Entity를 주문과 주문_음식 둘로 나눠 관계를 설정하였다. 그리고 이 또한 역시 위에 나열한 어노테이션을 이용하였다. 음... 그런데 솔직히 완벽한 정규화 개념을 가지고 접근했기 보다는... 어떻게 하면 여러행에 중복되는 데이터를 줄일 수 있을까라는 식의 의문을 가지며 접근했던 것 같다.

솔직히 아직 이제 맞는 것인지는 모르겠다. 다만 이렇게 수정을 하므로써 서비스 레이어에서 정보를 저장하고 가져와 응답하는 로직의 복잡함이 다소 해소된 것 같다.

profile
step by step

0개의 댓글