실전! 스프링 부트와 JPA 활용1(웹 애플리케이션 개발)

Ch02. 도메인 분석 설계 - 엔티티 설계시 주의점

webmaster 2021. 12. 3. 13:53
728x90

엔티티에는 가급적 Setter를 사용하지 말자 Setter가 모두 열려있다.

  • 변경 포인트가 너무 많아서, 유지보수가 어렵다. 나중에 리펙토링으로 Setter 제거

모든 연관관계는 지연 로딩으로 설정(매우 중요)

  • 즉시 로딩( EAGER )은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다.
    • 즉시 로딩 : 연관된 모든 테이블을 다 가지고 온다.
    • 성능상으로 문제가 많다(Lasy로 써서 원하는 것을 실시간으로 선택해서 가지고 와야 한다)
    • N+1 문제 발생 : EAGER로 되어 있을 경우 JPQL로 SELECT 문을 실행했을 때의 결과를 가지고 다시 연관된 테이블을 조회하기 위해 N개의 단건 쿼리가 실행된다
  • 실무에서 모든 연관관계는 지연 로딩( LAZY )으로 설정해야 한다.
  • 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다.
  • @XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시 로딩이므로 직접 지연 로딩으로 설정해야 한다

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

  • 컬렉션은 필드에서 바로 초기화하는 것이 안전하다.
  • null 문제에서 안전하다.
  • 하이버네이트는 엔티티를 영속화할 때, 컬랙션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다. 만약 getOrders()처럼 임의의 메서드에서 컬력션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문 제가 발생할 수 있다. 따라서 필드 레벨에서 생성하는 것이 가장 안전하고, 코드도 간결하다
Member member = new Member();
System.out.println(member.getOrders().getClass());
em.persist(team);
System.out.println(member.getOrders().getClass());
//출력 결과
class java.util.ArrayList
class org.hibernate.collection.internal.PersistentBag
  • 영속화가 시작되면 해당 객체는 하이버네이트가 PersistentBag으로 감싼다
  • 따라서 만약 개발자가 이 값을 set 해서 변경해 버리면 하이버네이트가 원하는 대로 동작하지 않을 수가 있다.

테이블, 칼럼명 생성 전략

스프링 부트에서 하이버네이트 기본 매핑 전략을 변경해서 실제 테이블 필드명은 다름

https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#howtoconfigure-hibernate-naming-strategy

 

Spring Boot Reference Guide

This section dives into the details of Spring Boot. Here you can learn about the key features that you may want to use and customize. If you have not already done so, you might want to read the "Part II, “Getting Started”" and "Part III, “Using Spr

docs.spring.io

 

Hibernate ORM 5.4.33.Final User Guide

Fetching, essentially, is the process of grabbing data from the database and making it available to the application. Tuning how an application does fetching is one of the biggest factors in determining how an application will perform. Fetching too much dat

docs.jboss.org

  • 하이버네이트 기존 구현: 엔티티의 필드명을 그대로 테이블의 컬럼명으로 사용 ( SpringPhysicalNamingStrategy )
  • 스프링 부트 신규 설정 (엔티티(필드) -> 테이블(컬럼))
    1. 카멜 케이스 -> 언더스코어(memberPoint member_point)
    2. .(점) ->(언더스코어)
    3. 대문자 -> 소문자
  • 적용 2 단계
    1. 논리명 생성: 명시적으로 칼럼, 테이블명을 직접 적지 않으면 ImplicitNamingStrategy 사용 spring.jpa.hibernate.naming.implicit-strategy : 테이블이나, 칼럼명을 명시하지 않을 때 논리명 적용,
    2. 물리명 적용: spring.jpa.hibernate.naming.physical-strategy : 모든 논리명에 적용됨, 실제 테이블에 적용 (username usernm 등으로 회사 룰로 바꿀 수 있음)

CasCasde 

참조되는 외래 키도 변경시켜 준다.

Order CascadeType 설정

연관관계 편이 메서드

Order 연관관계 편이 메소드
Category 연관관계 편이 메소드

  • 양방향 연관관계에서 한쪽에만 데이터를 넣는것을 방지하기 위해 연관관계 편의메소드를 작성한다.

 

728x90