220720_TIL : 참고사항

백승한·2022년 7월 20일
0

스프링

목록 보기
5/14
  • 섣부르게 개발을 하는 것 보다는 설계고민 시간을 오래 가져아한다.
    그래야 변화에 대응하기가 용이하다.
    ( 도메인 모델과 테이블 설계, 엔티티 분석 다이어그램, 테이블 분석 다이어그램 )

    급하다고 코드 대충 짜는거보단 더 고민하고 단계별로 테스트 하면서
    하나씩 넘어가는게 훨씬 더 시간 절약에 좋다.

    1. 엔티티 분석 다이어그램을 보면서 엔티티를 먼저 구현한다.
    2. 그다음 테이블 분석 다이어그램 보면서 매핑 확인
@Embedded // 내장 타입을 포함했다 라는 어노테이션으로 매핑
private Address address;

@OneToMany(mappedBy = "member") // 여기서 "member"는 Order에 있는 member필드에 의해서 매핑된 거울 역할
// mappedBy속성 : 나는 주인이 아니에요. 나는 연견관계의 거울이에요.(읽기 전용)
// ** mappedBy 속성을 해놓은 필드는 테이블에 컬럼이 존재하지 않는다. 
// Member 테이블에 orders 라는 칼럼은 없게 된다.
private List<Order> orders = new ArrayList<>();
  • OneToOne 연관관계 상황에서 참고
    FK 소유는 어느 객체를 더 많이쓰는냐에 따라 결정!
    Order와 Delivery가 OneToOne인데 배달로 Order를 찾기보다는
    Order를 보고 배달을 보기때문에 Order쪽에 FK를 둔다.
    그렇기 때문에 Order의 delivery필드에 조인컬럼을 설정!

  • 개발 순서: 서비스, 리포지토리 계층을 개발하고, 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용

참고

참고: 외래 키가 있는 곳을 연관관계의 주인으로 정해라.
연관관계의 주인은 단순히 외래 키를 누가 관리하냐의 문제이지 비즈니스상 우위에 있다고 주인으로 정하면 안된다.. 예를 들어서 자동차와 바퀴가 있으면, 일대다 관계에서 항상 다쪽에 외래 키가 있으므로 외래 키가 있는 바퀴를 연관관계의 주인으로 정하면 된다. 물론 자동차를 연관관계의 주인으로 정하는 것이 불가능 한 것은 아니지만, 자동차를 연관관계의 주인으로 정하면 자동차가 관리하지 않는 바퀴 테이블의 외래 키 값이 업데이트 되므로 관리와 유지보수가 어렵고, 추가적으로 별도의 업데이트 쿼리가 발생하는 성능 문제도 있다.

참고: 값 타입은 변경 불가능하게 설계해야 한다.
@Setter 를 제거하고, 생성자에서 값을 모두 초기화해서 변경 불가능한 클래스를 만들자. JPA 스펙상 엔티티나 임베디드 타입( @Embeddable )은 자바 기본 생성자(default constructor)를 public 또는 protected 로 설정해야 한다. public 으로 두는 것 보다는 protected 로 설정하는 것이 그나마 더 안전
하다. JPA가 이런 제약을 두는 이유는 JPA 구현 라이브러리가 객체를 생성할 때 리플랙션 / 프록시 같은 기술을 사용할 수 있도록 지원해야 하기 때문이다.

엔티티 설계시 주의점

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

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

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

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

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

  • 컬렉션은 필드에서 바로 초기화 하는 것이 안전하다.
  • null 문제에서 안전하다.
  • 하이버네이트는 엔티티를 영속화 할 때, 컬랙션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다. 만약 getOrders() 처럼 임의의 메서드에서 컬력션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다. 따라서 필드레벨에서 생성하는 것이 가장 안전하고, 코드도 간결하다.
profile
방문해주셔서 감사합니다🙂

0개의 댓글