Backend

[실전! 스프링부트와 JPA활용] 엔티티 설계 시 주의점

햣둘 2025. 4. 2. 07:56

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

Setter가 모두 열려있다. 

변경 포인트가 너무 많아서 유지보수가 어렵다.

나중에 리팩토링으로 Setter 제거

 

모든 연관관계는 지연로딩(LAZY)으로 설정!

즉시로딩(EAGER)은 예측이 어렵고 어떤 SQL이 실행될지 추적하기 어렵다.

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

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

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

@XToOne(OneToOne, ManyToOne) 관계는 디폴트값이 즉시로딩(EAGER)이므로 직접 지연로딩(LAZY)으로 설정하여 바꿔줘야 한다.

 

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

컬렉션은 필드에서 바로 초기화하는 것이 안전하다.

그래야 null 문제에서 안전하다.

하이버네이트는 엔티티를 영속화할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다.

만약 getOrders()처럼 임의의 메서드에서 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다.

따라서 필드 레벨에서 생성하는 것이 가장 안전하고 코드도 간결하다.

Member member = new Member();
System.out.println(member.getOrders().getClass());
em.persist(member);
System.out.println(member.getOrders().getClass());

// 출력 결과
class java.util.ArrayList
class org.hibernate.collection.internal.PersistentBag

 

테이블, 칼럼명 생성 전략

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

http://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#howto-configure-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

 

http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#naming

 

Index of /hibernate/orm/5.4/userguide/html_single

 

docs.jboss.org

 

하이버네이트 기존 구현 : 엔티티의 필드명을 그대로 테이블의 칼럼명으로 사용

(SpringPhysicalNamingStrategy)

 

스프링부트 신규 설정 : 엔티티(필드) -> 테이블(칼럼)

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

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

3. 대문자 -> 소문자

 

< 적용 2단계 >

1. 논리명 생성 : 명시적으로 칼럼, 테이블명을 직접 적지 않으면 ImplicitNamingStrategy 사용

spring.jpa.hibernate.naming.implicit-strategy : 테이블이나 칼럼명을 명시하지 않을 때 논리명 적용

2. 물리명 적용 : spring.jap.hibernate.naming.physical-strategy 모든 논리명에 적용됨

실제 테이블에 적용(username -> usernm 등으로 회사 규칙에 따라 바꿀 수 있음)

 

스프링 부트 기본 설정

spring.jpa.hibernate.naming.implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

spring.jpa.hibernate.naming.physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy