⚙️ 운영 환경까지 고려한 JPA 설정 가이드
1) 기본 설정
JPA 구동을 위한 가장 기본적인 설정 예시
spring:
datasource:
url: jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: validate
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: true
highlight_sql: true
jdbc:
time_zone: UTC
open-in-view: false
2) DDL 전략 선택 (ddl-auto)
spring.jpa.hibernate.ddl-auto 속성은 JPA가 엔티티와 DB 스키마를 어떻게 동기화할지를 결정하는 옵션이다. 선택 가능한 옵션과 의미는 다음과 같다.
- none / 미설정
- Hibernate가 스키마를 전혀 건드리지 않음 - validate
- 엔티티와 실제 테이블 구조가 일치하는지 검증만 하고 변경은 하지 않음 - update
- 엔티티 변경사항을 테이블에 반영(단 컬럼 삭제/타입 변경은 불완전) - create
- 실행 시 기존 스키마를 삭제 후 새로 생성 - create-drop
- 시작할 때 생성하고 애플리케이션 종료 시 삭제
개발, 운영, 테스트 환경에 따라 적절한 옵션을 선택하는 것이 중요하다. 운영 환경에서는 보통 validate 또는 none을 사용한다.
3) Hibernate Properties
[Dialect]
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
Dialect는 Hibernate가 SQL을 생성할 때 DB 벤더별 문법 차이를 흡수하기 위한 규칙 집합이다. 예를 들어 문자열 처리 함수(concat), 페이징 쿼리(limit/offset), 시퀀스 생성 등은 DB마다 문법이 다르므로 Dialect를 통해 적합한 SQL로 변환된다.
Spring Boot에서는 DataSource의 JDBC URL과 DB 메타데이터를 기반으로 Hibernate가 Dialect를 자동 감지한다.
[SQL 포맷팅]
spring:
jpa:
show-sql: true
hibernate:
format_sql: true
highlight_sql: true
show-sql은 Hibernate가 실행하는 SQL을 콘솔로 출력한다. 설정만 하면 로그 프레임워크를 거치지 않고 바로 확인이 가능하기 때문에 빠른 테스트/개발에 유용하다.
format_sql은 실행되는 SQL을 가독성 있게 줄바꿈/들여 쓰기 해서 보여주는 옵션이다. 추가로 highlight_sql을 같이 사용하면 콘솔 출력되는 SQL에 ANSI 컬러 코드를 적용하여 키워드를 색상으로 강조한다.
[JDBC Time Zone]
hibernate:
jdbc:
time_zone: UTC
DB에 저장·조회되는 timestamp, datetime 컬럼의 기준 타임존을 설정한다. 애플리케이션 서버와 DB 서버의 타임존이 다를 경우 발생할 수 있는 시간 불일치 문제를 예방한다.
4) Open-In-View
Open Session In View (OSIV) 패턴
spring:
jpa:
open-in-view: false
JPA/Hibernate는 영속성 컨텍스트(EntityManager, Session)가 열려 있어야 지연 로딩(Lazy Loading)이 가능하다. 기본적으로 Spring Boot는 open-in-view: true가 디폴트이기 때문에 컨트롤러 → 뷰 계층까지 영속성 컨텍스트를 열어둔다.
즉 서비스 계층에서 트랜잭션이 끝난 후에도 컨트롤러나 뷰에서 엔티티의 지연 로딩 필드를 호출할 수 있다. 따라서 open-in-view: false를 설정하여 서비스 계층까지만 영속성 컨텍스트를 열고 그 이후 컨트롤러/뷰 계층에서는 닫는다.
개발 환경에서는 편의상 true로 설정하기도 하지만 대부분 운영 환경에서는 성능, 안정성, 커넥션 관리 측면에서 open-in-view: false를 사용하는 경우가 많다. 대신 서비스 계층에서 필요한 데이터 로딩 전략을 확실히 설계하는 것이 중요하다.