JPA

JPA

연관관계

### 단반향 연관관계

CREATE TABLE MEMBER (
  ID BIGINT(20) NOT NULL AUTO_INCREMENT,
  TEAM_ID BIGINT(20),
  NAME VARCHAR(20),
  PRIMARY KEY (ID)
)

CREATE TABLE TEAM (
  ID BIGINT(20) NOT NULL AUTO_INCREMENT,
  NAME VARCHAR(20),
  PRIMARY KEY (ID)
)

ALTER TABLE MEMBER ADD CONSTRAINT FK_MEMBER_TEAM FOREIGN KEY (ID) REFERENCES TEAM

@Entity
public class Member {
  @Id
  @Column(name = "ID")
  private Long id;

  @Column(name = "NAME")
  private String name;

  @ManyToOne
  @JoinColumn(name="ID")
  private Team team;

}

@Entity
public class Team {
  @Id
  @Column(name="ID")
  private Long id;

  @Column(name="NAME")
  private String name;
}

### 양방향 연관관계 ### 연관관계의 주인 ### 양방향 연관관계 저장 ### 양방향 연관관계 주의점

N+1

  • 전체 조회 및 N 번 조회
  • Join Fetch (Inner Join)
  • @EntityGraph (Outer Join)

OSIV

  • OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어둔다는 뜻
  • 과거 OSIV : 요청 당 트랜잭션
    • OSIV의 핵심은 뷰에서도 지연 로딩이 가능하도록 하는 것
    • 클라이언트의 요청이 들어오자마자 서블릿 필터나 스프링 인터셉터에서 트랜잭션을 시작하고 요청이 끝날 때 트랜잭션도 끝내는 것
  • 요청 당 트랜잭션 방식의 OSIV 문제점
    • 프리젠텐이션 계층에서 수정된 내용이 데이터베이스까지 변경
    • 해결법
      • 엔티티를 읽기 전용 인터페이스로 제공
      • 엔티티 래핑
      • DTO만 반환
  • 스프링 OSIV : 비즈니스 계층 트랜잭션
    • 스프링 프레임워크가 제공하는 OSIV 라이브러리
    • 스프링 OSIV
      1. 클라이언트의 요청이 들어오면 서블릿 필터나, 스프링 인터셉터에서 영속성 컨텍스트를 생성 (트랜잭션 시작하지 않음)
      2. 서비스 계층에서 @Transaction로 트랜잭션을 시작할 때 1번에서 미리 생성해둔 영속성 컨텍스트를 찾아와서 트랜잭션을 시작
      3. 서비스 계층이 끝나면 트랜잭션을 커밋하고 영속성 컨텍스트를 플러시 (트랜잭션을 끝내지만 영속성 컨텍스트는 종료하지 않음)
      4. 컨트롤러와 뷰까지 영속성 컨텍스트가 유지되므로 조회한 엔티티는 영속 상태를 유지
      5. 서블릿 필터나, 스프링 인터셉터로 요청이 돌아오면 영속성 컨텍스트를 종료 (플러시를 호출하지 않고 바로 종료)
    • 스프링 OSIV 주의사항
      • 프리젠테이션 계층에서 엔티티를 수정 후 트랜잭션을 시작하는 서비스 계층을 호출하면 문제 발생
class MemberController {

  public String viewMember(Long id) {
    Member member = memberService.getMember(id);
    member.setName("***");

    memberService.biz();
    return "view";
  }
}

class MemberService {

  @Transcactional
  public void biz() {

  }
}

2차 캐시

  • 1차 캐시
    • 영속성 컨텍스트 내부에 있음
    • 엔티티 매니저로 조회하거나 변경하는 모든 엔티티는 1차 캐시에 저장
    • JAP를 J2EE나 스프링 프레임워크 같은 컨테이너 위에서 실행하면 컨텍스트도 종료
    • OSVI를 사용하면 요청의 시작부터 끝까지 같은 영속성 컨텍스트를 유지
  • 2차 캐시
    • 애플리케이션 범위의 캐시
    • 분산 캐시나 클러스터링 환경의 캐시는 애플리케이션보다 더 오래 유지될 수 있음
    • 2차 캐시의 동작 방식
      1. 영속성 컨텍스트는 엔티티가 필요한면 2차 캐시를 조회
      2. 2차 캐시에 엔티티가 없으면 데이터베이스를 조회
      3. 결과를 2차 캐시에 보관
      4. 2차 캐시는 자신이 보관하고 있는 엔티티를 복사해서 반환
      5. 2차 캐시에 저장되어 있는 엔티티를 조회하면 복사본을 만들어 반환