Entity Manager

- EntityManager는 Entity를 저장하고 수정하고 삭제하고 조회하는 (CRUD) 등 Entity와 관련된 모든 일을 처리함
- Thread Safe하지 않음. 여러 Thread에서 동시에 접근할 경우 동시성 이슈가 발생함
- EntityManager Factory가 각각의 request별 Thread안에 각각 만들어주게 됨. 그리고 db와의 작업을 위해서 connection을 획득함
- JPA의 구현체들은 EntityManagerFactory를 생성할 때 커넥션풀을 만듦
- Repository를 이때까지 만들어서 사용했지만 SimpleJpaRepository안에 EntityManager를 통하여 쿼리를 만들고 데이터를 불러옴. custom하게 하고 싶으면 EntityManager를 가지고 변형해야함
- Hibernate에서는 EntityManager를 session이라고 함
- 기본적으로 EntityManager에는 두가지 종류가 있다
- Container Managed EntityManager
- Application Managed EntityManager
Container-Managed EntityManager
- Spring에서는 EntityManager를 Proxy를 통해 감싸고 EntityManager를 사용할 때 Proxy를 통해 EntityManager를 생성함(Autowire로 EntityManager를 받으면 SharedEntityManagerCreator가 proxy를 통해 생성을 해줌 → 여러 스레드에서 동시 접근해도 Thread Safety를 보장해줌)
- 스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용함
- 트랜잭션이 시작할 때(tx.begin( )) 영속성 컨텍스트를 생성하고 트랜잭션이 끝날 때(tx.commit( )) 영속성 컨텍스트를 끝낸다.(by 컨테이너)
- 즉 @Transactional이 붙은 하나의 메서드를 시작하면서 영속성 컨텍스트 생성하고, 그 메서드가 끝나면 영속성 컨텍스트가 끝나는 것임!. 그 해당 메서드에 여러 request가 동시에 들어온다고 하더라도 별개의 트랜잭션이 생성되는 것이니 엔티티 매니저도 별개, 영속성 컨텍스트도 별개인 것!
- 트랜잭션이 같으면 같은 영속성 컨텍스트를 사용함(여러 EntityManager를 사용해도 한 트랜잭션으로 묶이면 영속성 컨텍스트를 공유함)
- 하나의 트랜잭션으로 묶인 메서드에 여러 request가 들어온다고 했을 때 하나의 트랜잭션으로 묶이니 영속성 컨텍스트는 공유한다는 것임
- 트랜잭션이 다르면 다른 영속성 컨텍스트를 사용함
- 같은 EntityManager를 사용해도 트랜젝션에 따라 접근하는 영속성 컨텍스트가 다르다
- 따라서 같은 EntityManager를 호출해도 접근하는 영속성 컨텍스트가 다르므로 멀티스레드에 안전함!
Application-Managed EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.baeldung.movie_catalog"); EntityManager em = emf.createEntityManager(); // 직접 생성.
- 우리가 직접 생성했으니, 닫는 것도 우리의 책임임