모르지 않다는 것은 아는것과 다르다.

Spring Jpa 13

JdbcTemplate을 활용하여 JPA의 saveAll() 대체하기

개요 JPA를 통해서 10만 건 이상의 데이터를 저장하는 경우 성능 이슈가 발생한다는 문의가 들어왔다. 평소에 나는 JPA로 대량의 데이터를 저장할 때에 성능적으로 문제가 있다는 사실은 알고 있었으나 그 원인을 정확히 설명하진 못했다. 이번 글에서는 위 문제를 해결하기 위한 과정을 정리해 보려고 한다. 결론부터 말하자면, 나는 JdbcTemplate의 batchUpdate() 메소드를 사용해서 문제를 해결했다. 먼저 Spring Data JPA의 saveAll()메소드의 실행 과정과 JdbcTemplate의 batchUpdate() 메소드의 실행 과정부터 알아보자. Spring Data JPA의 saveAll()메소드가 실행되는 과정 먼저 Spring Data JPA의 saveAll() 메소드가 실행되는..

Spring Jpa 2023.09.23

JPA에서 여러 종류의 영속성 관리하기

개요 JPA 기반의 애플리케이션에서 여러 개의 DB를 사용해서 개발하고 싶다는 요청이 들어왔다. 그렇다는 건, 여러 종류의 영속성을 사용하고 싶다는 의미다. 이 요구사항을 해결하기 위해서 여러 개의 Persistence-Unit을 정의하고, 그에 따라 여러 개의 EntityManagerFactory를 정의하는 과정을 진행했다. 이 과정에서 새로 알게된 내용들이 많아서 간단하게나마 정리해 보려고 한다. 먼저 JPA에서는 영속성을 관리하는 개념에 대해서 정리하고 넘어가자. JPA에서 영속성을 제어하기 위해서 필요한 구성요소 JPA에서 영속성을 관리하기 위해서는 위와 같은 구성요소가 세팅이 되어있어야 한다. 스프링부트를 사용하면 자동적으로 위와 같은 구성요소가 세팅이 된다. 구성요소 각각에 대해서 정리해 보자..

Spring Jpa 2023.08.28

JPA 관련 애노테이션 정리

@Repository 관련 persistence layer 를 구현하는 클래스에 사용한다. @Component 와 마찬가지로 해당 클래스를 빈으로 등록한다. persistence layer 에서 발생하는 예외를 잡아서 DataAccessException 으로 처리해준다. - PersistenceExceptionTranslationPostProcessor 가 처리한다. @Repository 와 관련된 Spring Data JPA 인터페이스 Repository: 기본 repository 인터페이스다. -> 어떤 메소드도 제공하지 않는다. CrudRepository: Repository + CRUD 기능 제공한다. PagingAndSortingRepository: CrudRepository + 페이징, 정렬 ..

Spring Jpa 2022.03.24

JPA DB 수동설정

DB 를 수동으로 설정해야할 경우 DB를 하나만 사용하면 굳이 수동으로 설저할 필요가 없다. 하지만 아래와 같은 경우엔 DB를 수동으로 설정할 필요가 있다. 자바 코드로 DataSource, TransactionManager 를 수동 세팅해야 하는 경우 configuration properties 로 커버되지 않는 세밀한 옵션을 줄 때 다중 DataSource 를 사용할 때 DB 세팅 요소 먼저 DataSource 를 세팅한다. -> DB 설정 그 다음 DataSource 를 바탕으로 EntityManagerFactory 를 세팅한다. -> PA 엔티티 관리 그 다음 EntityManagerFactory를 바탕으로 LocalContainerEntityManagerFactoryBean를 세팅한다. -> 트..

Spring Jpa 2022.03.24

프록시와 연관관계 관리

프록시 em.find() vs em.getReference() em.find(): 데이터베이스를 통해서 실제 엔티티 객체 조회 -> 바로 쿼리문을 날린다. em.getReference(): 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회 -> 실제로 사용될때 쿼리문을 날린다. 프록시의 구조 실제 클래스를 상속 받아서 만들어진다. 실제 클래스와 겉 모양이 같다. 사용하는 입장에서 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 된다. 프록시 객체의 초기화 client 가 getName()을 호출하면 MemberProxy 는 영속성 컨텍스트에 Member 객체를 요청한다. 영속성 컨텍스트는 DB를 조회해서 실제 엔티티 객체를 생성한다. 그리고 Member target에 생성된 엔티티 객체를 ..

Spring Jpa 2022.02.27

JPA Id 생성전략 설정하기

개요 보통 JPA 로 개발할때, @GeneratedValue(strategy = GenerationType.IDENTITY) 로 설정하고, 개발을 진행하였다. Id 값을 커스텀하게 생성할 수 있는 방법에 대해서 알아보려고 한다. @GeneratedValue @GeneratedValue는 식별자의 생성 전략을 지정하는데 사용된다. 전략은 아래와 같이 4가지 전략이 있다. IDENTITY 식별자 생성을 데이터베이스에 위임한다. 주로 MySQL, PostgreSQL, SQL Server 등에서 사용된다. 키 생성의 동시성 처리 도 데이터베이스에 위임한다. 엔티티가 persist 되는 시점에 즉시 INSERT SQL 을 실행 하고 DB 에서 식별자 값을 가져온다. SEQUENCE 데이터베이스의 시퀀스를 사용한다..

Spring Jpa 2022.02.27

영속성 컨텍스트

영속성 컨텍스트란? 엔티티를 영구 저장하는 환경 이라는 뜻이다. EntityManager.persist(entity); -> DB에 저장한다는 뜻이 아니라 엔티티를 영속성 컨텍스트에 저장한다는 말이다. 영속성 컨텍스트는 눈에 보이지 않는 논리적인 개념이다. 엔티티 메니저를 통해서 영속성 컨텍스트에 접근한다. 애플리케이션과 DB 사이에 있다고 생각하면 된다. 엔티티 컨텍스트 동작 방식 위와 같이 고객이 요청으하면 entityManagerFactory가 entityManager를 생성한다. entityManager는 내부적으로 DB connection을 통해서 DB와 통신한다. 엔티티의 생명주기 비영속 (new/transient) -> 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태 Member member..

Spring Jpa 2022.02.27

조회 성능 최적화

최적화 방법 먼저 @ManyToOne, @OneToOne 의 경우 fetch join을 이용해서 쿼리 수를 최적화 한다. @OneToMany 의 경우 페이징이 필요 없는 경우 -> fetch join을 이용해서 쿼리 수를 최적화 한다. 페이징이 필요한 경우 -> fetch join 을 사용하지 않는다. -> hibernate.default_batch_fetch_size 를 500 정도로 설정해서 최적화 한다. Entity 관계도 와 성능 문제 상황 위와 같이 주문, 주문상품, 고객, 배달, 상품 엔티티가 있다고 가정하자. 만약 주문 목록을 조회하는데 3개의 주문이 조회됐다. 여기서 주문과 고객, 배달이 toOne 으로 연결 되어있다. -> 몇번의 쿼리가 나갈까? order 목록을 조회하는 쿼리 1번 or..

Spring Jpa 2022.02.27

값타입

값 타입 분류 기본값 타임 자바 기본 타입(int, double) 래퍼 클래스(Integer, Long) String 임베디드 타입(embedded type, 복합 값 타입) 컬렉션 값 타입(collection value type) 기본값 타입 기본값 타입 생명주기를 엔티티의 의존한다. 회원을 삭제하면 이름, 나이 필드도 함께 삭제된다. 값 타입은 공유하면 안된다. ex> 회원 이름 변경시 다른 회원의 이름도 함께 변경되면 안된다. int, double 같은 기본 타입은 절대 공유되지 않는다. 하지만 Integer같은 래퍼 클래스나 String 같은 특수한 클래스는 공유 가능한 객체이지만 변경되지 않는다. 래퍼런스 참조이기 때문에 공유는 가능하지만 변경을 막아둬서 안전하게 사용할 수 있는 것이다. 임베디..

Spring Jpa 2022.02.27

OSIV

OSIV 란? OSIV(Open Session In View)는 영속성 컨텍스트를 뷰까지 열어두는 기능이다. 영속성 컨텍스트가 유지되면 엔티티도 영속 상태로 유지된다. 뷰까지 영속성 컨텍스트가 살아있다면 뷰에서도 지연 로딩을 사용할 수가 있다. OSIV ON spring.jpa.open-in-view : true -> 기본값이다. 애플리케이션 시작 시점에 warn 로그를 남긴다. OSIV 전략은 트랜잭션 시작처럼 최초 데이터베이스 커넥션 시작 시점부터 API 응답이 끝날 때 까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다. 동작 과정 1. 클라이언트의 요청이 들어오면 서블릿 필터나, 스프링 인터셉터에서 영속성 컨텍스트를 생성한다. 단 이 시점에서 트랜잭션은 시작하지 않는다. 2. 서비스 계층에서 @..

Spring Jpa 2022.02.27