JPA는 자바에서 제공하는 ORM기술에 대한 API표준.
ORM이란 'Object Relational Mappping'의 약자로 객체와 관계형 데이터베이스를 매핑해주는 것을 말함.
객체지향과 관계형 데이터베이스 간의 패러다임 불일치를 해결하기 위해 나온 기술이 ORM임. 객체는 객체지향적으로, 데이터베이스는 데이터베이스대로 설계함. ORM은 중간에서 2개를 매핑하는 역할. 이를 통해 개발자는 소스를 좀 더 객체지향적으로 설계하고 비즈니스 로직에 집중할 수 있음.
JPA는 인터페이스고, 이를 구현한 대표적인 구현체로 Hibernate, EclipseLink, DataNucleus, OpenJap, TopLink 등이 있음. 실질적인 기능은 Hibernate에 구현되어 있음.
JAP 사용 시 장점
-
특정 데이터베이스에 종속되지 않음.
- JPA는 추상화한 데이터 접근 계층을 제공하므로, 설정 파일에 어떤 데이터베이스를 사용하는지 알려주면 얼마든지 데이터베이스 변경 가능.
-
객체지향적 프로그래밍
-
생산성 향상
- 데이터베이스 테이블에 새로운 column이 추가되었을 경우, 해당 테이블의 column을 사용하는 dto 클래스 필드로 모두 변경해야 하지만, JPA에서는 테이블과 매핑된 클래스에 필드만 추가한다면 쉽게 관리가 가능함.
JAP 사용 시 단점
- 복잡한 쿼리 처리
- 성능 저하 위험
- 객체 간의 매핑 설계를 잘못했을 때 성능 저하가 발생. 자동으로 생성되는 쿼리가 많기 때문에 개발자가 의도하지 않는 쿼리로 인해 성능이 저하됨.
- 학습시간
JAP 동작방식

엔티티 생명주기


데이터베이스 반영 코드
- 영속성 컨텍스트에 저장할 상품 엔티티 생성.
new 키워드로 생성했으므로, 영속성 컨텍스트와 관련이 없는 상태.
Item item = new Item();
item.setItemNm("테스트 상품");
- 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성.
EntityManager em = entityManagerFactory.createEntityManager();
- 엔티티 매니저는 데이터 변경 시 데이터의 무결성을 위해 반드시 transaction 을 시작해야 함.
EntityTransaction transaction = em.getTransaction();
- 생성한 상품 엔티티가 영속성 컨텍스트에 저장된 상태. 여기까지는 데이터베이스에 INSERT SQL 을 보내지 않은 단계
em.persist(item);
- 트랜잭션을 데이터베이스에 반영. 이 때 영속성 컨텍스트에 저장된 상품 정보가 데이터베이스에 INSERT되면서 반영됨.
transaction.commit();
- 엔티티 매니저와 엔티티 매니저 팩토리의 close() 메서드를 호출해 사용한 자원을 반환함.
em.close();
emf.close();
영속성 컨텍스트 사용 시 이점

애플리테이션과 데이터베이스 사이에 영속성 컨텍스트 중간 계층을 만들면 버퍼링, 캐싱 등을 할 수 있는 장점이 있음.
- 1차 캐시
- 영속성 컨텍스트에는 1차 캐시가 존재하며 Map<Key, Value> 로 저장됨.
- entityManager.find() 메서드 호출 시 영속성 컨텍스트의 1차 캐시를 조회함. 엔티티가 존재할 경우 해당 엔티티를 반환하고, 엔티티가 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환.
- 동일성 보장
- 하나의 트랜잭션에서 같은 키값으로 영속성 컨텍스트에 저장된 엔티티 조회 시 같은 엔티티 조회를 보장함.
- 트랜잭션을 지원하는 쓰기 지연
- 영속성 컨텍스트에는 쓰기 지연 sql 저장소가 존재함.
- entityManager.persist() 를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 sql 저장소에 sql 문이 저장됨. 이렇게 sql을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 sql문들이 flush 되면서 데이터베이스에 반영.
- 변경 감지
- JPA는 1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷 값을 가지고 있음.
- 1차 캐시에 저장된 엔티티와 스냅샷을 비교 후 변경 내용이 있다면 update sql 문을 쓰기 지연 sql 저장소에 담아둠. 그리고 데이터베이스에 커밋시점에 변경 내용을 자동으로 반영함. 즉, 따로 update 문을 호출할 필요가 없음.
참고문헌
변구훈, 스프링부트 쇼핑몰 프로젝트 with JPA, 로드북