SpringBoot

Spring JPA 엔티티 설계 시 주의점

정ㅇr 2022. 7. 13. 14:38
728x90

현재 회사에서는 JPA를 사용하고 있지 않지만, 개인적으로 궁금하기도 하고 다른 회사에서도 사용하는 경우가 많아서

인프런에서 김영한님의 강의(실전 스프링부트와 JPA 활용 1)를 들으며 차근차근 배워 나가는 중이다.

 

엔티티 설계 주의점은 앞으로 JPA를 사용해서 개발하게 되면 아주 유용하게 쓰일 것 같아서

따로 블로그에 정리하려고 한다.

 

Spring JPA 엔티티 설계 시 주의점

1. 엔티티에는 가급적 Setter를 사용하지 말자.

 

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

- 즉시로딩 (EAGER)는 예측이 어렵고, 어떤 SQL이 실행될지 추적하기가 어려움

- 특히 JPQL을 싱행할 때, N+1 문제가 자주 발생한다.

- 실무에서는 모든 연관관계는 지연로딩 (LAZY)로 설정해야 함.

- 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다.

-  @??ToOne (예: OneToOne, ManyToOne ..) 관계는 기본 default가 fetch = FetchType.EAGER (즉시로딩)으로 되어 있기 때문에 반드시 fetch = FetchType.LAZY (지연로딩)으로 직접 설정해야 한다. ★중요함★

package com.jpabook.jpashop.domain;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "orders")
@Getter @Setter
public class Order {

    @Id @GeneratedValue
    @Column(name = "order_id")
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER) // 다대일 관계, 한 명의 주문자가 여러개의 주문을 할 수 있음
    @JoinColumn(name = "member_id") // FK name 지정
    private Member member;

    // JPQL(JPA 에서 제공하는 쿼리) 사용해서 데이터를 가져올 때 select o from order o; -> SQL는 다음과 같이 번역 select * from order
    // Order 하나를 조회할 때, Member가 다음과 같이 EAGER로 설정 되어 있을 경우에는
    // 만약 Member에 100개의 데이터가 있다면, Order 하나를 조회하기 위해서 Member를 조회하기 위한 쿼리가 100번 실행되는 상황이 발생된다.

    ...
}

 

3. 컬렉션은 필드에서 초기화 하자.

- null 문제에서 안전하다.

- 하이버네이트는 엔티티를 영속화(persist)할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변환한다. 컬렉션을 잘못 생성하게 되면, 하이버네이트 내부 메커니즘에 문제가 발생할 수 있으므로 필드에서 초기화하는게 안전하다.

 

 

4. 테이블, 컬럼명 생성 전략

- 하이버네이트 기존 구현 : 엔티티의 필드명을 그대로 테이블의 컬럼명으로 사용함 (SpringPhysicalNamingStrategy)

- 카멜케이스는 언더스코어로 바뀐다. (memberPoint -> member_point)

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

- 대문자는 소문자로 변경된다.

- 적용은 2단계로 구성되어 있는데, 논리명 / 물리명 적용으로 나뉜다,

- 논리명은 사용자가 명시적으로 컬럼, 테이블명을 적지 않으면 ImplicitNamingStrategy를 사용하게 된다.

- 물리명은 모든 논리명에 적용되고, 실제 테이블에 적용된다. 회사 룰에 맞춰서 사용자가 테이블명을 직접 변경할 수 있다.


 참고

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1

 

깃허브

강의를 들으면서 소스코드를 작성한 레파지토리

https://github.com/Jung-Ah-C/springboot-jpa-project

 

반응형