클래스 들어가기 -> ctrl+b
상세 보기 -> alt+enter
변수 자동 생성 -> ctrl+alt+v
닫기 -> ctrl+f4
프로젝트 구조 -> ctrl+alt+shift+s
경로 찾기 -> ctrl+shift+f
코드 합치기 -> ctrl+shift+n
테스트 생성, 이동 -> ctrl+shift+t
메서드 -> ctrl+alt+m
최근 검색 창 -> ctrl+e
전체 변수명 바꾸기 -> shift+f6
- Entity 설계시 setter를 사용 하지 말자
- 변경 포인트가 많아 져서 유지보수가 어렵다.
- 모든 연관관계는 지연로딩으로 설정!!!!!
- 즉시 로딩(EAGER)은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생
- 실무에서 모든 연관관계는 지연로딩(LAZY)으로 설정해야 한다.
- 연관된 엔티티를 함꼐 DB에서 조회해야 하면, fetch join 또는 엔티티 그래프 기능을 사용한다.
- @XToOne 관계는 기본 즉시 로딩이므로 직접 지연로딩을 해줘야 한다.
- 컬렉션은 필드에서 초기화 하자.
컬렉션은 필드에서 바로 초기화 하는 것이 안전하다.
- null 문제에서 안전하다.
- 하이버네이트는 엔티티를 영속화 할 때, 컬렉션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다 임의의 메서드에서 컬렉션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다. 따라서 필드레벨에서 생성하는 것이 안전하고, 코드도 간결하다.
- 테이블, 컬럼명 생성 전략
- 하이버네이트 기조 구현: 엔티티의 필드명을 그대로 테이블 명으로 구현
- 스프링 부트 신규 설정 (SpringPhysicalNamingStrategy)
- memberPoint -> member_point
- . -> _
- 대문자 -> 소문자
- 논리명, 물리명
- 회원기능
- 등록, 조회
- 상품기능
- 등록, 수정, 조회
- 주문기능
- 상품 주문
- 주문 내역 조회
- 주문 취소
참고 주문 서비스의 주문과 주문 취소 메서드를 보면 비즈니스 로직 대부분이 에티티에 있다. 서비스 계층은 단순히 엔티티에 필요한 요청을 위임하는 역할을 한다. 이처럼 엔티티가 비즈니스 로직을 가지고 객체 지향의 특성을 적극 활용하는 것을 도메인 모델 패턴 이라한다.
반대로 엔티티에는 비즈니스 로직 없고 서비스 계층에서 대부분의 로직을 처리하는 것을 트랜잭션 스크립트 패턴 이라한다.
JPA에서 동적 쿼리를 어떻게 해결해야 하는가 쿼리 dsl
BindingResult Entity는 순수 , DTO 작성 -> api 작성시 절대로 entity 반환 하지면 안된다.
변경 감지와 병합
준영속 엔티티? 영속컨테스트 관리 안하는 엔티티
변경감지 == dirty checking
엔티티를 변경할 때는 항상 변경 감지를 사용하세요.
단순 서비스가 레포지토리 위임이면 레포지토리 바로 접근 해도 된다.
- 실무에서 엔티티로 외부로 노출 시키거나 파라미터를 받는 행위는 하지 않아야한다.
준비 단계
지연 로딩 때문에 발생하는 성능 문제를 단계적으로 해결해보자.
참고 엄청 중요한 내용이다.
- 엔티티 직접 노출시 양방향 연관관계가 걸린 곳은 @jsonIgnore처리 안 그러면 무한 루프, 노출 시키지 마세요!
- DTO로 보내는 것이 좋다.
- 성능 최적화를 위해 패치 조인을 사용해라!
쿼리 방식 선택 권장 설정
- 우선 엔티티를 DTO로 변환하는 방법 선택
- 필요하면 패치 조인으로 성능 최적화
- 그래도 안되면 DTO로 직접 조회
- 최후는 SQL직접 사용
컬렉션을 패치 조인하면 페이징이 불가능하다. 다대일로 가야한다.
컬렉션 패치 조인을 하면 데이터가 부정합하게 조회될 수 있다.
- 모든 XToOne은 패치 조인 해준다.
- 컬렉션은 지연 로딩으로 조회환다.
- hibernate.default_batch_fetch_size를 적용한다. 컬렉션이나, 프록시 객체를 한꺼번에 설정한 size 만큼 IN 퀄리로 조회한다.
Open Session In View : 하이버네이트
Open EntityManager In View: JPA
관례상 OSIV라 한다.
JPA에서는 Open EntityManager In View, OEIV 라고하며, 하이버네이트에서는 OSIV라고 부르지만 같은 기능이다.
OSIV 전략은 트랜잭션 시작시 최초 데이터베이스 커넥션 시작 시점부터 API응답이 끝날 때(View) 까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다.
즉, View 레이어에서도 지연로딩을 사용할 수 있다.
스프링이 제공하는 OSIV는 서블릿 또는 인터셉터에서 적용이 가능하며, OSIV사용시 영속성 컨텍스트는 View 레이어까지 지속되지만 영속상태의 객체를 수정할경우에는 트랜잭션 안에서만 가능하다.
실시간 트래픽이 중요한 애플리케이션에서는 커넥션이 모자랄 수 있다. 이것은 장애로 이어진다. spring.jpa.open-in-view: false 모든 지연로딩을 트랜잭션 안에서 처리해야 한다. 결론적으로 트랜잭션이 끝나기 전에 지연 로딩을 강제로 호출해 두어야 한다.