[Spring] JPA hibernate의 ddl-auto 속성
JPA의 구현체 중 하나인 하이버네이트는 다양한 기능을 제공하는데,
그 중 엔티티만 작성해놓으면 자동으로 테이블을 생성하거나 수정해주는 ddl-auto 라는 설정이 있다.
create, create-drop, update, validate, none 이렇게 속성이 있는데, 여기서는 create과 update에 대해서만 작성한다.
create
create은 애플리케이션을 실행할 때마다 테이블을 자동으로 생성해준다.
실행 시 데이터베이스에 해당 테이블이 존재하지 않으면 새로 테이블을 생성하고, 이미 테이블이 존재한다면 drop 후 다시 생성한다.
하지만 이 옵션은 기존의 데이터가 모두 삭제되고 새로운 테이블이 생성되기 때문에, 실제 운영 환경에서는 절대 사용하면 안된다고 한다.
update
update도 실행 시 해당 테이블이 존재하지 않으면 테이블을 자동 생성해준다.
다만 create와 다른 점은 기존 테이블이 존재한다면 create처럼 테이블을 삭제시키고 새로 생성하는 것이 아니라,
현재 엔티티 클래스와 데이터베이스 스키마를 동기화한다고 생각하는 것이 맞다. 엔티티와 디비 테이블을 같게 만든다고 할 수 있다.
하지만, 모든 변경사항을 반영하는 것은 아니다. 기존에 존재하는 컬럼 속성(타입, nullable, 크기)은 건드리지 않고, 새로운 컬럼이 추가되는 변경사항만 반영한다.
예를 들어, 어떤 엔티티 클래스의 String을 Int로 바꿨다고 치자. ddl-auto=update를 한다면 타입이 변경되지 않고 String으로 유지된다.
- 개발 초기 단계, 로컬에서 테스트: create 또는 update
- 테스트 서버: update
- 운영 서버: validate 또는 none
ddl-auto 속성들은 얼핏 보기에 테이블을 자동 생성해준다는 점에서 굉장히 편리해보이지만 validate나 none을 제외한 속성은 운영 DB에서는 절대 사용하면 안된다고 한다.
그나마 update라면 낫지만, (이것도 문제가 될 수 있는게 만약 update로 새로 추가한 컬럼이 not null이라면 해당 변경사항이 반영되지 않은 버전을 배포했을 때, 데이터가 삽입이 안될 수도 있다.)
create로 설정한 상태에서 운영 DB에 연결하여 애플리케이션을 실행한다면 운영 DB의 테이블이 다 삭제되는 대참사가 발생한다.
Spring에서 다중 Profile 사용 시
다중 프로파일을 사용하여 스프링부트 프로젝트 속성을 관리한다면, 운영 프로파일의 ddl-auto는 반드시 validate나 없어야 한다.
즉, 공통 속성(default)에 작성하지 않고 ddl-auto는 각 프로파일의 속성에 작성해야 한다.
요약
- create: 기존 스키마 삭제(drop) 후 다시 생성
- update: 엔티티와 DB 테이블 비교 후, 엔티티에 추가되는 변화가 있으면 DB 칼럼 추가(제거는 X)
- validate: 엔티티와 테이블이 같은지만 확인. 일치하지 않으면 에러 발생
- none(default)