본문 바로가기
Backend/JPA & QueryDSL

[JPA] JPA 관련 설정(properties, yml)

by 제이동 개발자 2023. 7. 15.
728x90

JPA 관련 설정(properties, yml)

Hibernate ORM 6.1.7.Final User Guide (jboss.org)

 

Hibernate ORM 6.1.7.Final User Guide

Fetching, essentially, is the process of grabbing data from the database and making it available to the application. Tuning how an application does fetching is one of the biggest factors in determining how an application will perform. Fetching too much dat

docs.jboss.org

 

1. 쿼리 로그 관련 설정

1-1. show_sql

  • System.out을 이용하여 하이버네이트 SQL 실행 쿼리를 출력
  • 정렬된 형태가 아닌 한 줄로 출력
  • System.out을 이용하여 출력하기 때문에 운영 서버에서 사용하는 것을 권장하지 않음
spring:
  jpa:
    properties:
      hibernate:
        show_sql: true
Hibernate: select member0_.member_id as member_i1_0_, member0_.name as name2_0_ from member member0_

 

1-2. use_sql_comments

  • System.out을 이용하여 하이버네이트 JPQL 쿼리를 출력
  • SQL 실행 쿼리 앞에 comment /* ... */ 형태로 출력
  • 출력되는 쿼리(show_sql, org.hibernate.SQL)가 없으면 use_sql_comments도 출력되지 않음
  • System.out을 이용하여 출력하기 때문에 운영 서버에서 사용하는 것을 권장하지 않음
spring:
  jpa:
    properties:
      hibernate:
        show_sql: true
        use_sql_comments: true
Hibernate: /* select member1.id
from Member member1
where member1.name = ?1 */ select m1_0.id from member m1_0 where m1_0.name=? limit ?

 

1-3. format_sql

  • 출력되는 SQL, JPQL을 정렬된 형태로 출력
spring:
  jpa:
    properties:
      hibernate:
        show_sql: true
        use_sql_comments: true
        format_sql: true
Hibernate: 
    /* select
        member1.id 
    from
        Member member1 
    where
        member1.name = ?1 */ select
            m1_0.id 
        from
            member m1_0 
        where
            m1_0.name=? limit ?

 

1-4. org.hibernate.SQL

  • logger를 통해 하이버네이트 실행 SQL을 출력
  • logger를 통해 출력하기 때문에 보통 운영 서버에서 사용
  • 아래 테스트는 format_sql 옵션을 추가한 결과
spring:
  jpa:
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org.hibernate.SQL: DEBUG
2023-03-01T14:34:08.922+09:00 DEBUG 3220 --- [           main] org.hibernate.SQL                        : 
    /* select
        member1.id 
    from
        Member member1 
    where
        member1.name = ?1 */ select
            m1_0.id 
        from
            member m1_0 
        where
            m1_0.name=? limit ?

 

1-5. Spring Boot 2.X : org.hibernate.type
       Spring Boot 3.X : org.hibernate.orm.jdbc.bind

  • SQL 실행 쿼리에 ?로 출력된 파라미터들을 출력
  • 해당 쿼리에 어떤 파라미터가 바인딩되어 쿼리가 실행되는지 확인하고자 할 때 사용
  • Spring Boot 버전에 따른 설정
    • Spring Boot 2.X - org.hibernate.type
    • Spring Boot 3.X - org.hibernate.orm.jdbc.bind
// Spring Boot 2.X
logging:
  level:
    org.hibernate.SQL: debug
    org.hibernate.type: trace
    
// Spring Boot 3.X
logging:
  level:
    org.hibernate.SQL: debug
    org.hibernate.orm.jdbc.bind: trace
2023-03-01T15:21:06.433+09:00 DEBUG 5196 --- [           main] org.hibernate.SQL                        : 
    select
        m1_0.id 
    from
        member m1_0 
    where
        m1_0.name=? limit ?
2023-03-01T15:21:06.436+09:00 TRACE 5196 --- [           main] org.hibernate.orm.jdbc.bind              : binding parameter [1] as [VARCHAR] - [test3500000]
2023-03-01T15:21:06.437+09:00 TRACE 5196 --- [           main] org.hibernate.orm.jdbc.bind              : binding parameter [2] as [INTEGER] - [1]

 

 

2. 데이터 베이스 초기화 전략

  • create : drop & create
    테이블을 모두 제거하고 다시 생성
  • create-drop : drop & create & drop
    테이블을 모두 제거하고 다시 생성 후 애플리케이션 종료 시 테이블 모두 제거
  • update 
    테이블의 변경점만 반영
  • validate
    현재 테이블 정보가 Entity에 정의된 내용과 동일한지 체크, 다를 경우 경고를 출력하며 실행되지 않음
  • none
    사용하지 않음
spring:
  jpa:
    hibernate:
      ddl-auto: create # option : creqte, create-drop, update, validate, none

 

 

3. 배치 설정

  • 참조 객체를 조회할 때 설정한 사이즈만큼 in 쿼리를 이용하여 조회
spring:
  jpa:
    properties:
      hibernate:
        default_batch_fetch_size: 1000

 

 

4. OSIV 설정

  • 영속성 컨텍스트의 생명주기를 설정
    • true
      - view의 모든 랜더링이 이루어질 때까지 영속성 컨텍스트를 유지
      - 즉, 클라이언트에게 응답할 때까지 유지
    • false
      - 트랜젝션과 생명주기가 동일
      - 트랜잭션이 종료되면 영속성 컨텍스트도 종료
spring:
  jpa:
    open-in-view: false

 

 

5. 네이밍 전략(Hibernate Naming Strategy)

  • 데이터베이스의 column 네이밍 전략
  • 기본 값으로는 camel case → snake case 인 SpringPhysicalNamingStrategy를 사용
    • SpringPhysicalNamingStrategy : camel case → snake case
    • PhysicalNamingStrategyStandardImpl : 엔티티의 각 필드명 그대로 적용
spring:
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

 

 

6. Query Plan Cache 설정

더보기

Query Plan Cache 란?

JPQL 쿼리 혹은 Criteria 쿼리들은 AST(Abstract Syntax Trr)으로 파싱 되어 하이버네이트가 SQL문을 실행할 수 있게 합니다. 이와 같은 쿼리 컴파일 시간을 단축시키기 위해 하이버네이트가 사용하는 것이 Query Plan Cache입니다.

 

JPA에서 in 절을 사용하는 경우 Query Plan Cache가 과하게 메모리를 사용하는 문제가 발생할 수 있습니다. 이 때문에 서버의 응답이 느려지거나, 가비지 컬렉션이 자주 실행되는 현상이 발생합니다.

 

예시를 보면 다음과 같습니다.

select * from product in (1);
select * from product in (1, 2);
select * from product in (1, 2, 3);
select * from product in (1, 2, 3, 4);
select * from product in (1, 2, 3, 4, 5);
select * from product in (1, 2, 3, 4, 5, 6);
----------------------------------
select * from product in (?);
select * from product in (?, ?);
select * from product in (?, ?, ?);
select * from product in (?, ?, ?, ?);
select * from product in (?, ?, ?, ?, ?);
select * from product in (?, ?, ?, ?, ?, ?);

 위 6개 쿼리를 실행하게 되면 Query Plan Cache에 총 6개 쿼리가 모두 저장되어 메모리를 많이 사용하는 문제가 발생합니다. 매개변수의 개수가 모두 다르기 때문에 6개 쿼리가 Query Plan Cache에 저장되는데 이를 해결하기 위해서 사용하는 것이 바로 in_clause_parameter_padding 입니다. 

 in_clause_parameter_padding=true 로 설정하여 위 6개 쿼리를 다시 실행하면 다음과 같습니다.

select * from product in (1, 1);
select * from product in (1, 2);
select * from product in (1, 2, 3, 3);
select * from product in (1, 2, 3, 4);
select * from product in (1, 2, 3, 4, 5, 5, 5, 5);
select * from product in (1, 2, 3, 4, 5, 6, 6, 6);
---------------------------------
select * from product in (?, ?);
select * from product in (?, ?, ?, ?);
select * from product in (?, ?, ?, ?, ?, ?, ?, ?);

 6개 쿼리가 Query Plan Cache에 저장되었던 것과는 달리 총 3개의 쿼리가 저장되어 사용된 것을 볼 수 있습니다. 그 이유는 in_clause_parameter_padding 설정을 true로 하게 되면 in 절의 매개변수를 2의 제곱단위로 쿼리를 만들어 사용하기 때문에 Query Plan Cache에 3개의 쿼리만 저장됩니다.

 

 따라서 in 절을 자주 사용해야 한다면 in_clause_parameter_padding 설정을 추가하여 메모리 점유를 낮추거나, 성능을 향상할 수 있습니다.

spring:
  jpa:
    properties:
      hibernate:
        plan_cache_max_size: 2048  # QueryPlanCache size 설정, 기본값 2048
        in_clause_parameter_padding: true  # QueryPlanCache padding 설정
        plan_parameter_metadata_max_size: 2048  # ParameterMetadata size 설정, 기본값 2048, 네이티브 쿼리인 경우 하이버네이트에서 파라미터와 반환 타입에 대한 정보를 저장

 

 

728x90