JPA 내부 구조
김영한
SI, J2EE 강사, DAUM, SK 플래닛

저서: 자바 ORM 표준 JPA 프로그래밍
목차
• 영속성 컨텍스트
• 프록시와 즉시로딩, 지연로딩
영속성 컨텍스트
JPA에서 가장 중요한 2가지
• 객체와 관계형 데이터베이스 매핑하기

(Object Relational Mapping)
• 영속성 컨텍스트
엔티티 매니저 팩토리와
엔티티 매니저
영속성 컨텍스트
• JPA를 이해하는데 가장 중요한 용어
• “엔티티를 영구 저장하는 환경”이라는 뜻
• EntityManager.persist(entity);
엔티티 매니저?
영속성 컨텍스트?
• 영속성 컨텍스트는 논리적인 개념
• 눈에 보이지 않는다.
• 엔티티 매니저를 통해서 영속성 컨텍스트에 접근
J2SE 환경

엔티티 매니저와 영속성 컨텍스트가 1:1
EntityManager
J2EE, 스프링 프레임워크 같은 컨테이너 환경 

엔티티 매니저와 영속성 컨텍스트가 N:1
EntityManager
EntityManager
EntityManager PersistenceContext
1:1
N:1
PersistenceContext
엔티티의 생명주기
• 비영속 (new/transient)

영속성 컨텍스트와 전혀 관계가 없는 상태
• 영속 (managed)

영속성 컨텍스트에 저장된 상태
• 준영속 (detached)

영속성 컨텍스트에 저장되었다가 분리된 상태
• 삭제 (removed)

삭제된 상태
엔티티의 생명주기
비영속
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
영속
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername(“회원1”);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//객체를 저장한 상태(영속)
em.persist(member);
준영속, 삭제
//회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member);
//객체를 삭제한 상태(삭제)
em.remove(member);
영속성 컨텍스트의 이점
• 1차 캐시
• 동일성(identity) 보장
• 트랜잭션을 지원하는 쓰기 지연

(transactional write-behind)
• 변경 감지(Dirty Checking)
• 지연 로딩(Lazy Loading)
엔티티 조회, 1차 캐시
//엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//엔티티를 영속
em.persist(member);
1차 캐시에서 조회
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//1차 캐시에 저장됨
em.persist(member);
//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");
데이터베이스에서 조회
Member findMember2 = em.find(Member.class, "member2");
영속 엔티티의 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); //동일성 비교 true
1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭
션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공
엔티티 등록
트랜잭션을 지원하는 쓰기 지연
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
em.persist(memberA);
em.persist(memberB);
transaction.commit();
엔티티 수정

변경 감지
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
//em.update(member) 이런 코드가 있어야 하지 않을까?
transaction.commit(); // [트랜잭션] 커밋
변경 감지
(Dirty Checking)
엔티티 삭제
//삭제 대상 엔티티 조회
Member memberA = em.find(Member.class, “memberA");
em.remove(memberA); //엔티티 삭제
플러시
영속성 컨텍스트의 변경내용을

데이터베이스에 반영
플러시 발생
• 변경 감지
• 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
• 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송 

(등록, 수정, 삭제 쿼리)
영속성 컨텍스트를

플러시하는 방법
• em.flush() - 직접 호출
• 트랜잭션 커밋 - 플러시 자동 호출
• JPQL 쿼리 실행 - 플러시 자동 호출
JPQL 쿼리 실행시 플러시가 자동
으로 호출되는 이유
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//중간에 JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
플러시 모드 옵션
• FlushModeType.AUTO

커밋이나 쿼리를 실행할 때 플러시 (기본값)
• FlushModeType.COMMIT

커밋할 때만 플러시
em.setFlushMode(FlushModeType.COMMIT)
플러시는!
• 영속성 컨텍스트를 비우지 않음
• 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
• 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화
하면 됨
준영속 상태
• 영속 -> 준영속
• 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
• 영속성 컨텍스트가 제공하는 기능을 사용 못함
준영속 상태로 만드는 방법
• em.detach(entity)

특정 엔티티만 준영속 상태로 전환
• em.clear()

영속성 컨텍스트를 완전히 초기화
• em.close()

영속성 컨텍스트를 종료
프록시와 즉시로딩, 지연로딩
Member를 조회할 때 Team도 함께 조회해야 할까?
Member Team
단순히 member 정보만 사용하는 비즈니스 로직
println(member.getName());
지연 로딩 LAZY을 사용해서 프록시로 조회
@Entity

public class Member {



@Id

@GeneratedValue

private Long id;



@Column(name = "USERNAME")

private String name;



@ManyToOne(fetch = FetchType.LAZY) //**

@JoinColumn(name = "TEAM_ID")

private Team team;

..
}
지연 로딩 LAZY을 사용해서 프록시로 조회
Member Team
Team team = member.getTeam();
team.getName(); // 실제 team을 사용하는 시점에 초기화(DB 조회)
Member Team
Member member = em.find(Member.class, 1L);
LAZY
Member와 Team을 자주 함께 사용한다면?
Member Team
즉시 로딩 EAGER를 사용해서 함께 조회
@Entity

public class Member {



@Id

@GeneratedValue

private Long id;



@Column(name = "USERNAME")

private String name;



@ManyToOne(fetch = FetchType.EAGER) //**

@JoinColumn(name = "TEAM_ID")

private Team team;

..
}
즉시 로딩(EAGER), Member조회시 항상 Team도 조회
Member Team
EAGER
JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회
프록시와 즉시로딩 주의
• 가급적 지연 로딩을 사용
• 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생
• 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다.
• @ManyToOne, @OneToOne은 기본이 즉시 로딩

-> LAZY로 설정
• @OneToMany, @ManyToMany는 기본이 지연 로딩
실습 ex06
• 즉시 로딩과 지연 로딩시 쿼리 확인

More Related Content

PDF
DDD 구현기초 (거의 Final 버전)
PDF
Domain Driven Design
PDF
Jpa 잘 (하는 척) 하기
PDF
도메인 주도 설계의 본질
PDF
Ksug2015 - JPA2, JPA 기초와매핑
PPTX
Hibernate ppt
PPT
Java Persistence API (JPA) Step By Step
PDF
Spring Data JPA
DDD 구현기초 (거의 Final 버전)
Domain Driven Design
Jpa 잘 (하는 척) 하기
도메인 주도 설계의 본질
Ksug2015 - JPA2, JPA 기초와매핑
Hibernate ppt
Java Persistence API (JPA) Step By Step
Spring Data JPA

What's hot (20)

PDF
Rich domain model
PDF
Spring Data JPA
PPTX
Java 11 to 17 : What's new !?
PDF
Spring 2.0 技術手冊第一章 - 認識 Spring
PPTX
Angular
PDF
애플리케이션 아키텍처와 객체지향
PPT
Hibernate Tutorial
PDF
Spring bootでweb セキュリティ(ログイン認証)編
PDF
[2018] MyBatis에서 JPA로
PDF
우아한 객체지향
PDF
DDD 준비 서문래
PDF
객체지향적인 도메인 레이어 구축하기
PDF
Dependency Injection
PDF
Repository and Unit Of Work Design Patterns
PDF
なかったらINSERTしたいし、あるならロック取りたいやん?
PPTX
Reflection in C#
PDF
Roles, Responsibilities, Collaborations
PPTX
Spring Boot and REST API
PDF
Domain Modeling Made Functional (DevTernity 2022)
PPTX
Spring data jpa
Rich domain model
Spring Data JPA
Java 11 to 17 : What's new !?
Spring 2.0 技術手冊第一章 - 認識 Spring
Angular
애플리케이션 아키텍처와 객체지향
Hibernate Tutorial
Spring bootでweb セキュリティ(ログイン認証)編
[2018] MyBatis에서 JPA로
우아한 객체지향
DDD 준비 서문래
객체지향적인 도메인 레이어 구축하기
Dependency Injection
Repository and Unit Of Work Design Patterns
なかったらINSERTしたいし、あるならロック取りたいやん?
Reflection in C#
Roles, Responsibilities, Collaborations
Spring Boot and REST API
Domain Modeling Made Functional (DevTernity 2022)
Spring data jpa
Ad

Viewers also liked (20)

PDF
Ksug2015 jpa5 스프링과jpa
PDF
Ksug2015 jpa4 객체지향쿼리
PDF
Ksug2015 - JPA1, JPA 소개
PDF
SpringDataJPA - 스프링 캠프
PDF
좌충우돌 ORM 개발기 2012 DAUM DEVON
PDF
Querydsl
PPTX
영속성 컨텍스트로 보는 JPA
PDF
아라한사의 스프링 시큐리티 정리
PDF
[162] jpa와 모던 자바 데이터 저장 기술
PDF
JPA 상속관계 매핑(@MappedSuperclass, @Inheritance,@DiscriminatorValue,@Discriminato...
PPTX
Apresentação da Avaliação de Aprendizagem e processos do 2° ano do ensino médio
PDF
진큐 오버뷰
PDF
Growing object oriented software guided by test
PDF
스프링 Generic autowired 로 구현하는 제너릭 컨트롤러 이야기
PDF
Aws ses 이메일 보내기 받기 송신 수신
PDF
스프링 Generic autowired이용해보기
PDF
jQuery angular, React.js 로 댓글달아보기 공부했던 기록
PDF
스프링 데이터 레디스 엘라스틱 발표자료
PDF
Hibernate start (하이버네이트 시작하기)
PDF
스프링 REST DOCS 따라해보기
Ksug2015 jpa5 스프링과jpa
Ksug2015 jpa4 객체지향쿼리
Ksug2015 - JPA1, JPA 소개
SpringDataJPA - 스프링 캠프
좌충우돌 ORM 개발기 2012 DAUM DEVON
Querydsl
영속성 컨텍스트로 보는 JPA
아라한사의 스프링 시큐리티 정리
[162] jpa와 모던 자바 데이터 저장 기술
JPA 상속관계 매핑(@MappedSuperclass, @Inheritance,@DiscriminatorValue,@Discriminato...
Apresentação da Avaliação de Aprendizagem e processos do 2° ano do ensino médio
진큐 오버뷰
Growing object oriented software guided by test
스프링 Generic autowired 로 구현하는 제너릭 컨트롤러 이야기
Aws ses 이메일 보내기 받기 송신 수신
스프링 Generic autowired이용해보기
jQuery angular, React.js 로 댓글달아보기 공부했던 기록
스프링 데이터 레디스 엘라스틱 발표자료
Hibernate start (하이버네이트 시작하기)
스프링 REST DOCS 따라해보기
Ad

Similar to Ksug2015 - JPA3, JPA 내부구조 (20)

PPTX
(JPA 엔티티 매니저)JPA 기초강좌, 엔티티 매니저. 엔티티 매니저팩토리
PPTX
Java JPA
PDF
JPA 관련 스터디내용입니다. 천천히 다가가기천천히 다가가기천천히 다가가기천천히 다가가기
PPTX
Sql 중심 코드 탈피
PPTX
멋쟁이사자처럼_백엔드_멘토_강의자료_MVC 패턴과 영속성 컨텍스트.pptx
PPTX
Sql 중심 코드 탈피 발표자료
PPTX
MyBatis에서 JPA로
PDF
아키텍트가 바라보는 Spring framework
PDF
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
PPTX
NDC 11 자이언트 서버의 비밀
PDF
[Study]HeadFirst JSP&servlet chapter5
PPTX
영속성 컨텍스트(Persistence context)_자바학원추천/구로IT학원/JPA학원/스프핑학원/자바교육
PDF
JPA Study - 1주차(SLIPP)
PPTX
Free rtos seminar
PDF
Jpa 쿼리 포함 자료
PDF
Jpa 쿼리 포함 자료
PPTX
Effective c++ 1~8장
PPTX
하이버네이트의 영속성 컨텍스트와 패치 전략
PDF
03.실행환경 교육교재(배치처리)
PPTX
Whole part pattern
 
(JPA 엔티티 매니저)JPA 기초강좌, 엔티티 매니저. 엔티티 매니저팩토리
Java JPA
JPA 관련 스터디내용입니다. 천천히 다가가기천천히 다가가기천천히 다가가기천천히 다가가기
Sql 중심 코드 탈피
멋쟁이사자처럼_백엔드_멘토_강의자료_MVC 패턴과 영속성 컨텍스트.pptx
Sql 중심 코드 탈피 발표자료
MyBatis에서 JPA로
아키텍트가 바라보는 Spring framework
자바 웹 개발 시작하기 (6주차 : 커뮤니티를 만들어보자!)
NDC 11 자이언트 서버의 비밀
[Study]HeadFirst JSP&servlet chapter5
영속성 컨텍스트(Persistence context)_자바학원추천/구로IT학원/JPA학원/스프핑학원/자바교육
JPA Study - 1주차(SLIPP)
Free rtos seminar
Jpa 쿼리 포함 자료
Jpa 쿼리 포함 자료
Effective c++ 1~8장
하이버네이트의 영속성 컨텍스트와 패치 전략
03.실행환경 교육교재(배치처리)
Whole part pattern
 

Ksug2015 - JPA3, JPA 내부구조

  • 2. 김영한 SI, J2EE 강사, DAUM, SK 플래닛 저서: 자바 ORM 표준 JPA 프로그래밍
  • 3. 목차 • 영속성 컨텍스트 • 프록시와 즉시로딩, 지연로딩
  • 5. JPA에서 가장 중요한 2가지 • 객체와 관계형 데이터베이스 매핑하기
 (Object Relational Mapping) • 영속성 컨텍스트
  • 7. 영속성 컨텍스트 • JPA를 이해하는데 가장 중요한 용어 • “엔티티를 영구 저장하는 환경”이라는 뜻 • EntityManager.persist(entity);
  • 8. 엔티티 매니저? 영속성 컨텍스트? • 영속성 컨텍스트는 논리적인 개념 • 눈에 보이지 않는다. • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근
  • 9. J2SE 환경
 엔티티 매니저와 영속성 컨텍스트가 1:1 EntityManager J2EE, 스프링 프레임워크 같은 컨테이너 환경 
 엔티티 매니저와 영속성 컨텍스트가 N:1 EntityManager EntityManager EntityManager PersistenceContext 1:1 N:1 PersistenceContext
  • 10. 엔티티의 생명주기 • 비영속 (new/transient)
 영속성 컨텍스트와 전혀 관계가 없는 상태 • 영속 (managed)
 영속성 컨텍스트에 저장된 상태 • 준영속 (detached)
 영속성 컨텍스트에 저장되었다가 분리된 상태 • 삭제 (removed)
 삭제된 상태
  • 12. 비영속 //객체를 생성한 상태(비영속) Member member = new Member(); member.setId("member1"); member.setUsername("회원1");
  • 13. 영속 //객체를 생성한 상태(비영속) Member member = new Member(); member.setId("member1"); member.setUsername(“회원1”); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); //객체를 저장한 상태(영속) em.persist(member);
  • 14. 준영속, 삭제 //회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태 em.detach(member); //객체를 삭제한 상태(삭제) em.remove(member);
  • 15. 영속성 컨텍스트의 이점 • 1차 캐시 • 동일성(identity) 보장 • 트랜잭션을 지원하는 쓰기 지연
 (transactional write-behind) • 변경 감지(Dirty Checking) • 지연 로딩(Lazy Loading)
  • 16. 엔티티 조회, 1차 캐시 //엔티티를 생성한 상태(비영속) Member member = new Member(); member.setId("member1"); member.setUsername("회원1"); //엔티티를 영속 em.persist(member);
  • 17. 1차 캐시에서 조회 Member member = new Member(); member.setId("member1"); member.setUsername("회원1"); //1차 캐시에 저장됨 em.persist(member); //1차 캐시에서 조회 Member findMember = em.find(Member.class, "member1");
  • 18. 데이터베이스에서 조회 Member findMember2 = em.find(Member.class, "member2");
  • 19. 영속 엔티티의 동일성 보장 Member a = em.find(Member.class, "member1"); Member b = em.find(Member.class, "member1"); System.out.println(a == b); //동일성 비교 true 1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭 션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공
  • 20. 엔티티 등록 트랜잭션을 지원하는 쓰기 지연 EntityManager em = emf.createEntityManager(); EntityTransaction transaction = em.getTransaction(); //엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다. transaction.begin(); // [트랜잭션] 시작 em.persist(memberA); em.persist(memberB); //여기까지 INSERT SQL을 데이터베이스에 보내지 않는다. //커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다. transaction.commit(); // [트랜잭션] 커밋
  • 23. 엔티티 수정
 변경 감지 EntityManager em = emf.createEntityManager(); EntityTransaction transaction = em.getTransaction(); transaction.begin(); // [트랜잭션] 시작 // 영속 엔티티 조회 Member memberA = em.find(Member.class, "memberA"); // 영속 엔티티 데이터 수정 memberA.setUsername("hi"); memberA.setAge(10); //em.update(member) 이런 코드가 있어야 하지 않을까? transaction.commit(); // [트랜잭션] 커밋
  • 25. 엔티티 삭제 //삭제 대상 엔티티 조회 Member memberA = em.find(Member.class, “memberA"); em.remove(memberA); //엔티티 삭제
  • 27. 플러시 발생 • 변경 감지 • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록 • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송 
 (등록, 수정, 삭제 쿼리)
  • 28. 영속성 컨텍스트를
 플러시하는 방법 • em.flush() - 직접 호출 • 트랜잭션 커밋 - 플러시 자동 호출 • JPQL 쿼리 실행 - 플러시 자동 호출
  • 29. JPQL 쿼리 실행시 플러시가 자동 으로 호출되는 이유 em.persist(memberA); em.persist(memberB); em.persist(memberC); //중간에 JPQL 실행 query = em.createQuery("select m from Member m", Member.class); List<Member> members= query.getResultList();
  • 30. 플러시 모드 옵션 • FlushModeType.AUTO
 커밋이나 쿼리를 실행할 때 플러시 (기본값) • FlushModeType.COMMIT
 커밋할 때만 플러시 em.setFlushMode(FlushModeType.COMMIT)
  • 31. 플러시는! • 영속성 컨텍스트를 비우지 않음 • 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화 • 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화 하면 됨
  • 32. 준영속 상태 • 영속 -> 준영속 • 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached) • 영속성 컨텍스트가 제공하는 기능을 사용 못함
  • 33. 준영속 상태로 만드는 방법 • em.detach(entity)
 특정 엔티티만 준영속 상태로 전환 • em.clear()
 영속성 컨텍스트를 완전히 초기화 • em.close()
 영속성 컨텍스트를 종료
  • 35. Member를 조회할 때 Team도 함께 조회해야 할까? Member Team 단순히 member 정보만 사용하는 비즈니스 로직 println(member.getName());
  • 36. 지연 로딩 LAZY을 사용해서 프록시로 조회 @Entity
 public class Member {
 
 @Id
 @GeneratedValue
 private Long id;
 
 @Column(name = "USERNAME")
 private String name;
 
 @ManyToOne(fetch = FetchType.LAZY) //**
 @JoinColumn(name = "TEAM_ID")
 private Team team;
 .. }
  • 37. 지연 로딩 LAZY을 사용해서 프록시로 조회 Member Team Team team = member.getTeam(); team.getName(); // 실제 team을 사용하는 시점에 초기화(DB 조회) Member Team Member member = em.find(Member.class, 1L); LAZY
  • 38. Member와 Team을 자주 함께 사용한다면? Member Team
  • 39. 즉시 로딩 EAGER를 사용해서 함께 조회 @Entity
 public class Member {
 
 @Id
 @GeneratedValue
 private Long id;
 
 @Column(name = "USERNAME")
 private String name;
 
 @ManyToOne(fetch = FetchType.EAGER) //**
 @JoinColumn(name = "TEAM_ID")
 private Team team;
 .. }
  • 40. 즉시 로딩(EAGER), Member조회시 항상 Team도 조회 Member Team EAGER JPA 구현체는 가능하면 조인을 사용해서 SQL 한번에 함께 조회
  • 41. 프록시와 즉시로딩 주의 • 가급적 지연 로딩을 사용 • 즉시 로딩을 적용하면 예상하지 못한 SQL이 발생 • 즉시 로딩은 JPQL에서 N+1 문제를 일으킨다. • @ManyToOne, @OneToOne은 기본이 즉시 로딩
 -> LAZY로 설정 • @OneToMany, @ManyToMany는 기본이 지연 로딩
  • 42. 실습 ex06 • 즉시 로딩과 지연 로딩시 쿼리 확인