[JPA 활용 1] Entity 설계 시 주의점 🙆‍♂️

홍정완·2022년 4월 24일
0

JPA

목록 보기
6/38
post-thumbnail

엔티티 설계 시 주의점 🙆‍♂️




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


Setter가 모두 열려있다 -> 변경 포인트가 너무 많아서 유지 보수가 어렵다.




2. 모든 연관관계는 지연 로딩(fetch = FetchType.LAZY)으로 설정하자


즉시 로딩은 특정 엔티티를 조회할 때(로딩될 때) 연관된 모든 엔티티를 조회한다.


기본적으로 전부 지연 로딩(LAZY)로 세팅을 하고 필요에 따라 연관된 원하는 엔티티를 같이 조회할 경우,
fetch join 또는 엔티티 그래프로 최적화를 하는 것이 좋다.


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

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

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

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

  • @xToOne(OnToOne, ManyToOne) 관계는 기본 패치 전략이 즉시 로딩(EAGER)이므로 직접 지연 로딩(LAZY) 설정을 해야 한다.

    • @xToMany(OnToMany, ManyToMany) 관계는 기본 패치 전략이 지연 로딩(LAZY)이다.

  • @xToOne의 관계일 경우 단건만 조회하면 EAGER 전략이 합리적일 것 같지만 여러 개를 조회하는 상황이 발생할 경우 N+1 문제가 발생한다 따라서 기본을 LAZY로 세팅하는 게 합리적이다.



3. cascade를 사용하여 Persist를 전파하자 (영속성 전이)


상위 엔티티가 변경될 경우 상위 엔티티의 연관된 하위 엔티티같이 변경을 전파해 주는 옵션이다.


즉, 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들 수 있다.


JPA Cascade Type


  • ALL : 하위 엔티티로 모든 작업을 적용
  • PERSIST : 하위 엔티티까지 영속성 적용
  • MERGE : 하위 엔티티까지 병합
  • REMOVE : 하위 엔티티까지 삭제
  • REFRESH : 하위 엔티티까지 인스턴스 값 새로고침
  • DETACH : 하위 엔티티까지 영속성 제거



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


  • List, Set, Queue, Map 등

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

  • 'NULL'문제에서 안전하다.

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

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

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


Member member = new Member();
System.out.println(member.getOrders().getClass()); // 1번
em.persist(team);
System.out.println(member.getOrders().getClass()); // 2번

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



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


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


하이버네이트 기존 구현 :

1. 엔티티의 필드명을 그대로 테이블의 컬럼명으로 사용 (SpringPhysicalNamingStrategy)


스프링 부트 신규 설정 :

1. 카멜 케이스 -> 언더 스코어(memberPoint -> member_point)
2. .(점) -> _(언더 스코어)
3. 대문자 -> 소문자


profile
습관이 전부다.

0개의 댓글