ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 엔티티 설계시 주의점
    JPA/JPA 활용 2023. 7. 11. 18:08

    1. 엔티티에는 Setter를 되도록 사용하지 않아야한다.

    - 공부를 할 때에는 Setter를 사용했지만 실제로 Setter가 모두 열려있으면, 유지 보수가 어렵다.

     

     

    2. 모든 연관관계는 지연로딩으로 설정

    모든 연관관계는 지연로딩(LAZY)로 설정해야 한다. 즉시로딩(EAGER)은 예측이 어렵고 JPQL을 실행할 때 N+1 문제 등이 자주 발생한다. 데이터 하나를 가져올 때 그 데이터 뿐만 아니라 연관된 모든 데이터를 가져오기때문에 에러가 빈번하게 발생한다. 만약에 연관된 엔티티를 함께 DB에서 조회해야할 상황이면 fetch join 또는 엔티티 그래프 기능을 사용하면 된다.

     

    OneToMany는 기본이 LAZY지만, OneToOne, ManyToOne은 기본이 EAGER이기때문에 필수로 LAZY로 변경해주어야 한다.

    @ManyToOne(fetch = FetchType.LAZY)

    애노테이션 뒤에 (fetch = FetchType.LAZY)를 붙여주면 된다.

     

     

    3. 테이블, 컬럼명 생성

    @Table(name = "orders")

    위의 애노테이션으로 테이블 명을 설정할 수 있다. 따로 테이블명을 설정하지 않으면 디폴트 값이 들어간다.

     

    스프링 부트에서 설정하는 방법

    1.   카멜 케이스 -> 언더스코어(memberPoint -> member_point)

    2.   .(점) -> _(언더스코어)

    3.   대문자 -> 소문자

     

     

    4. caseCade

    @Entity
    @Table(name = "orders") // 이거 하지 않으면 관례로 order로 들어감
    @Getter @Setter
    public class Order {
    
        @Id @GeneratedValue
        @Column(name = "order_id")
        private Long id;
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "member_id") // FK(foreign key)
        private Member member;
    
        @OneToMany(mappedBy =  "order", cascade = CascadeType.ALL)
        //order에 의해서 mapping이 되었다는 뜻
        private List<OrderItem> orderItems = new ArrayList<>();
    

    order의 일부분을 먼저 살켜보면 orderItems라는 리스트가 있는데, order를 저장할 때에 리스트를 하나씩 persist 해줘야한다.

    persist(orderItemA)

    persist(orderItemB)

    persist(orderItemC)

    persist(order)

    와 같이 persist를 진행해야하는데, cascade는 모든 엔티티를 각각 persist하지 않고, order만 persist해도 같이 persist가 되는 기능이다.

     

     

    5. 연관관계 메서드

    DB끼리 연관관계가 있을 때 서로의 엔티티에서 다른 엔티티에 접근할 경우가 있을수도 있다. 예를들어, order와 member는 연관관계가 있는데, order.member에서도 접근하고, member.order에서도 접근하여서 양방향으로 접근할 수 있게 만들 수 있다.

    // 연관관계 메서드//
    public void setMember(Member member) {
        this.member = member;
        member.getOrders().add(this);
    }
    
    public void addOrderItem(OrderItem orderItem) {
        orderItems.add(orderItem);
        orderItem.setOrder(this);
    }
    
    public void setDelivery(Delivery delivery) {
        this.delivery = delivery;
        delivery.setOrder(this);
    }

    Order 엔티티 아래에 연관관계 메서드를 추가해줄 수 있다. db에는 연관관계 매핑을 통해서 값이 동일하게 저장되지만 객체의 입장에서 보면 order에서도 member를 호출할 수 있고, member에서도 order를 호출 할 수 있어야한다.

     

     

    public void setMember(Member member) {
            this.member = member;
            member.getOrders().add(this);
        }
        /*
            Member member = new Member();
            Order order = new Order();
    
            member.getOrders().add(order);
            order.setMember(member);
            // 원래는 이렇게 적어야하는데 연관관계 메서드로 묶어주는 과정이다.
         */

    연관관계 메서드의 맨 위인 member와의 연관관계를 살펴보면 원래는 주석처리된 것과 같이 양쪽에 둘 다 값을 넣어줘야하는데, 이러한 것들을 편리하게 만들어주는 것이 연관관계 메서드라고 할 수 있다.

Designed by Tistory.