2. JPA 기초와 매핑
Last updated
Last updated
@Entity : JPA 가 관리할 객체 엔티티라 한다.
@Id : DB PK 와 매핑 할 필드
데이터베이스 방언
JPA 는 특정 데이터베이스에 종속적이지 않은 기술
각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다르다.
가변 문자 : MySQL 은
VARCHAR
, Oracle 은VARCHAR2
문자열을 자르는 함수 : SQL 표준은
SUBSTRING()
, Oracle 은SUBSTR()
페이징 : MySQL 은
LIMIT
, Oracle 은ROWNUM
방언 : SQL 표준을 지키지 않거나 특정 데이터베이스만의 고유한 기능
표준화하려고 해도 Oracle 에서 따라주지 않는다.. (시장 점유율을 빼앗기고 싶지 않다.. )
프로젝트 내에서 아래 설정을 통해서 다른 DB 벤더를 사용하더라도 간단하게 확장할 수 있다.
아래 설정을 통해 H2 DB 와 연결해준다.
사실 코드는 별거 없다..
당연히 테이블은 먼저 생성해두어야겠지?
여기서 의존성을 주입해주는 EntityManagerFactory
는 스프링이 올라갈 때 스프링 컨테너에 기본적으로 등록되기 때문에, 어디서든 사용할 수 있다.
application.properties
설정 내용을 기반으로 생성된다.
한번 실행하면 DB 에 저장되기 때문에, 두번째 실행부터는 PK 충돌 오류가 난다.
저장 안되는 설정은 찾아보자..
EntityManagerFactory
는 하나만 생성해서 애플리케이션 전체에서 공유해야 한다. 비용이 높은 리소스
EntityManagerFactory
는 내부적으로 데이터베이스 연결 풀을 관리하고,
엔티티 매핑 정보를 로드하며,
Hibernate 와 같은 JPA 구현체를 로드해
이런 초기화 작업에는 많은 리소스와 시간이 소요되기 때문에, 빈번하게 생성하면 성능이 저하될 수 있어
데이터 일관성 문제
EntityManagerFactory
는 2차 캐시를 관리해
만약 애플리케이션에서 여러 개의 EntityManagerFactory
를 사용한다면, 각 팩토리가 별도의 2차 캐시를 가지므로 일관성이 깨질 수 있다.
데이터베이스 연결 부족
여러 개의 EntityManagerFactory
가 생성되면, 데이터베이스 연결 풀을 중복으로 관리하게 되고
데이터베이스 연결 제한이 초과되면 새로운 연결을 열 수 없게된다.
스레드 안전
EntityManagerFactory
는 스레드 안전하게 설계되어 있어서, 여러 스레드에서 동시에 사용해도 안전해
따라서 애플리케이션 전체에서 공유해도 문제가 없어.
EntityManager
는 쓰레드간 공유하면 안된다. (사용하고 버려야 한다) EntityManager
란?
EntityManager
는 JPA 에서 데이터베이스와 상호작용하기위한 핵심 객체로, 엔티티의 CRUD 등 작업을 담당
엔티티 상태를 관리하며, 데이터베이스와의 트랜잭션을 처리하는 역할도 수행한다.
EntityManger
는 엔티티 객체의 상태(영속성 컨텍스트) 를 관리하는데, 이 컨텍스트는 EntityManager
인스턴스마다 독립적으로 존재하며, 한 트랜잭션 동안만 유지된다.
이때, 여러 스레드에서 동시에 접근하면 영속성 컨텍스트가 손상될 가능성이 크다. (DB 커넥션을 여러사람이 공유하는 꼴이다..)
또한, 하나의 트랜잭션에서 관리되는 엔티티 객체는 EntityManager 에 종속적이므로, 다른 스레드에서 사용하면 트랜잭션이 꼬이거나 상태가 일관되지 않을 수 있다.