Avatar 창조적이고 생산적이고 싶은 개발자

#2 JPA 실무 - 엔티티 설계 시 주의사항

엔티티 설계 시 주의해야 하는 사항들

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

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

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

  • EAGER fetch는 예측이 어렵고, 어떤 SQL이 실행될 지 추적하기 어렵다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다.
  • 실무에서 모든 연관관계는 LAZY fetch로 설정.
  • 연관된 엔티티를 함께 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프를 사용
  • @XtoOne 관계는 기본이 EAGER fetch가 기본이므로 LAZY fetch로 설정해야함.

Collection은 반드시 필드에서 초기화하자.

  • null문제에서 안정하다.
  • 하이버네이트는 엔티티를 영속화 할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다(PersistentBag). 만약 선언된 컬렉션을 다른 인스턴스로 변경하거나하면 하이버네이트 내부 매커니즘에 문제가 발생할 수 있다.

테이블, 컬럼명 생성 전략

  • boot기준으로 camel case -> snake case
  • .(dot) -> _(under score)
  • 대문자 -> 소문자

적용 2단계

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

# default : org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.hibernate.naming.implicit-strategy
  • 테이블이나, 컬럼명을 명시하지 않을때 논리명 적용

물리명 적용

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

모든 논리명에 적용됨, 실제 테이블에 적용(username -> usernm 등으로 회사 룰로 바꿀 수 있음)

cascade

cascade를 설정하면 PERSIST, DELETE 등의 처리를 영속화 처리할 때 연관된 엔티티도 같이 처리할 수 있음. 다만 DB에서와 마찬가지로 cascading으로 인해 보존해야 할 데이터가 삭제되거나 하는 이슈가 있을 수 있으므로 주의해서 사용

연관관계 편의 메소드

  • 양방향 연관관계인 경우 한쪽에서만 setter를 제공하는게 더 복잡하지 않고 안전하다.
    public void setMeber(Member meber) {
      this.member = meber;
      member.getOrders().add(this);
    }