Home JPA - 예제 구현
Post
Cancel

JPA - 예제 구현

예제 구현

https://github.com/ISSuh/spring_shop_example

엔티티 설계시 주의점

외래 키가 있는 곳을 연관관계의 주인으로 정할 것 연관관계의 주인은 단순히 외래 키를 누가 관리하냐의 문제이지 비지니스상 우위에 있다고 주인으로 정하면 안됨.

예를 들어 자동차와 바퀴가 있다면, 일대다 관계에서 항상 다쪽에 외래 키가 있으므로 외래 키가 있는 바퀴를 연관관계의 주인으로 정하면 됨. 물론 자동차를 연관관계의 주인으로 정하는 것이 불가능 한 것은 아니지만 자동차를 연관관계의 주인으로 정하면 자동차가 관리하지 않는 바퀴 테이블의 외래 키 값이 업데이트 되므로 관리와 유지보수에 어렵고 추가적으로 별도의 업데이트 쿼리가 발생하는 성능 문제도 발생 함.

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

  • Setter가 모두 열려있다면 변경 포인트가 너무 많아서 유지보수에 어려움이 있음

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

  • 즉시로딩(EAGER)은 예측이 어렵고 어떤 SQL이 실행될지 추철하기 어려움
    • 특히 JPQL을 실행할 떄 N+1 문제가 자주 발생할 수 있음
  • 실무에서 모든 연관관계는 지연로딩(LAZY)로 설정해야 함
  • 연관된 엔티티를 함꼐 DB에서 조회해야 한다면, fetch join또는 엔티티 그래프 기능을 사용
  • @XToOne(OneToOne, ManyToOne)관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정해야 함

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

  • 컬렉션은 필드에서 바로 초기화하는것이 null 문제에 대해 안전함
  • 하이버네이트는 엔티티를 영송화 할 뗴, 컬렉션을 감싸허 하이버네이트가 제공하는 내장 컬레션으로 변경하는데, 만약 getOrder()처럼 임의의 메소드에서 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있음. 그러므로 필드레벨에서 생성하는 것이 가장 안전하고 코드도 간결해짐

폼객체 vs 엔티티 직접 사용

요구사항이 정말 단순할 떄는 폼 객체 없이 엔티티를 직접 등록과 수정화면에서 사용해도 됨. 그러나 화면 요구사항이 복잡해지기 시작하면 엔티티에 화면을 처리하기 위한 기능이 증가하게 되면서 결국 엔티티는 화면에 종속적으로 변하게 되버림. 실무에서는 엔티티는 핵심 비지니스 로직만 가지고 있고, 화면을 위한 로직은 없어야 함. 화면이나 API에 맞는 폼 객체나 DTO를 사용하여 요구사항을 처리하고 엔티티는 순수하게 유지하는것이 좋음.

API를 만들떄는 엔티티를 반환하지 않는것이 좋음

  • 엔티티를 변경하면 API의 스펙도 변경되어 버림

참고

  • 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발(김영한)
This post is licensed under CC BY 4.0 by the author.