이번 글에선 자바 JPA 에 대해 알아보고자 한다. 자바 JPA 란 ORM (Object–relational mapping) 기법을 자바에 적용하기 위해 만들어진 API 표준 이다. 인터페이스로서의 역할만 하기 때문에 실질적인 구현체들은 자바에서 제공해주는 JPA 를 인터페이스로 사용하여 만들어져 있다.
대표적인 JPA 구현체들은 Hibernate, EclipseLink, DataNucleus, OpenJap, TopLink 등이 있고 하고 개인적으론 Hibernate 만 써보아서 각 구현체들에 대한 장단점은 아직 잘 모르겠다.
그리고 Java JPA 에선 영속성 컨텍스트(Persistence Context) 라는 개념이 나오는데 JPA 에선 이 영속성 컨텍스트에 대해 꼭 알아야한다.
그럼 영속성 컨텍스트 (Persistence Context)란 무엇인가?
DB 테이블과 1:1 맵핑되는 객체 즉 Entity 라고 부르는 객체가 저장되는 환경이자 논리 개념이다. 라라벨로 치환하자면 JPA 만을 위한 서비스 컨테이너가 따로 있다고 생각하면 될거 같다. 엔티티들은 영속성 컨텍스트에 key(식별자) - value(엔티티) 구조로 맵핑되며 이것을 영속 상태라고 부른다. 영속 상태의 엔티티는 식별자 값이 반드시 있어야 한다.(없다면 예외 발생)
엔티티 조회
엔티티 저장
엔티티 수정
DB 에 저장된/저장할 Entity 들을 캐싱 해놓고 관리하는데 이를 1차 캐시라고 부른다. 그리고 이 영속성 컨텍스트는 EntityManager 라는 JPA 인터페이스를 구현한 객체를 통해 관리할수 있다. (조회, 업데이트, 삭제)등의 일들은 EntityManager 를 통해 처리해야 한다.
이런식으로 영속성 컨텍스트를 따로두어 얻을수 있는 특징 및 이점은 다음과 같다.
- 1차 캐시
엔티티 조회시 바로 DB 에 쿼리를 날려 조회해오지 않고 영속성 컨텍스트에 찾고자 하는 엔티티가 있는지 먼저 확인한뒤에 없다면 DB 에 쿼리를 날려 조회해오기 때문에 성능상 이점이 있다. - 엔티티의 동일성 보장
데이터베이스 테이블의 특정한 한 행을 메모리상에서 표현함으로 인해 데이터베이스의 동일성과 자바의 동일성(같은 메모리를 참조하는 값)을 만족 시킴. - 쓰기 지연
트랜잭션을 걸어 INSERT 쿼리를 DB에 바로 날리지 않고 1차 캐시에 저장하는 동시에 쓰기 지연 SQL 저장소에 쌓아두었다가 트랜잭션 commit 일때 DB 에 쿼리를 날림. 이는 DB 와 필요한 순간에만 통신을 하기 때문에 DB 테이블 Row 에 Lock 이 걸리는 것을 최소화 하는 이점이 있다. - 변경 감지
트랜잭션 커밋시 영속성 컨텍스트에 같은 Entity 가 저장되어 있다면 변경된 값을 비교하여 찾고 있다면 수정 쿼리를 생성하여 DB 에 쿼리를 날린다. DirtyChecking 이라 부르며 수정 작업에 쓰인다.
이외에도 merge를 통한 엔티티 수정 방법이 있는데 이는 사이드이펙트가 발생할 확률이 높아 쓰지 않는 것이 좋다.(변경되지 않은 모든 다른 값에 대해선 디폴트로 null 로 맵핑하여 업데이트 한다.)
그리고 이 EntityManager 는 EntityManagerFactory에 의해 스레드당 하나씩 할당된다. (여러 스레드가 동시에 접근시 동시성문제가 발생하기 때문)
EntityManagerFactory - EntityManager
간단히 JPA 가 무엇인지 어떻게 동작하는지 알아보았다. 개인적으론 라라벨 프레임워크를 사용해왔기 때문에 익숙한 개념들도 있고 새로운 개념도 있는데 라라벨과 비교해보며 배우는 재미가 있는것 같다. 그리고 스프링 프레임워크가 좀더 추상화가 많이 된것 같다. 대표적으로 이를 느꼈던게 crud 를 JPA 에서 트랜잭션 형태로 관리를 해주는것이다. 편의성은 더 좋은거 같은데 더 추상화가 된 만큼 그 기저에 깔린 작동원리를 제대로 이해할 필요가 있을거 같다.
참고
- https://ultrakain.gitbooks.io/jpa/content/chapter3/chapter3.4.html
- https://velog.io/@neptunes032/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80
- https://willseungh0.tistory.com/65
'IT > 스프링' 카테고리의 다른 글
[Spring] 스프링부트 AOP 구현 및 예제 (0) | 2023.10.20 |
---|---|
[Springboot] 스프링 AOP (Aspect Oriented Programming) 에 대해서 (0) | 2023.10.10 |
[spring] 스프링부트 어노테이션 @Bean, @Component 차이 (1) | 2023.10.02 |