Spring Boot를 사용하면서 DataSource initialization에 대한 여러 방법을 알아보자.
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization
Initialize a Database Using JPA
JPA를 사용하는 경우 JPA에 DDL 생성 기능이 있다.
이는 다음 properties를 통해 설정할 수 있다.
- spring.jpa.generate-ddl (boolean) vendor에 독립적으로 활성화/비활성화, default false
- spring.jpa.hibernate.ddl-auto (enum) 은 보다 세분화된 방식으로 동작을 제어
generate-ddl을 true로 설정하면 entity에 설정된 기준으로 database에 테이블을 생성하고 변경될 때마다 갱신한다.
spring.jpa.generate-ddl=true
Initialize a Database Using Hibernate
spring.jpa.hibernate.ddl-auto로 설정할 수 있고 none, validate, update, create, create-drop을 설정할 수 있다.
default 값은 embedded database 인지 여부에 따라 다르다.
schema manager가 없으면 create-drop으로 설정되며 그 외의 경우 none으로 설정된다.
# none, validate, update, create, create-drop
spring.jpa.hibernate.ddl-auto=create
또한 Hibernate가 schema를 처음부터 생성하는 경우 (즉, ddl-auto 속성이 create 또는 create-drop으로 설정된 경우) class path의 root에 위치한 import.sql 이름의 파일이 applciation이 시작될 때 실행된다.
Initialize a Database Using Basic SQL Scripts
Spring Boot는 JDBC DataSource 또는 R2DBC ConnectionFactory의 schema (DDL script)를 자동으로 생성하고 initialize (DML script) 할 수 있다.
각각 root class path 위치의 schema.sql 과 data.sql에서 SQL을 로드한다.
또한 spring.sql.init.platform 값이 사용하고 schema-${platform}.sql 과 data-${platform}.sql 파일이 있는 경우 해당 파일도 처리한다.
이를 통해 필요한 경우 database 특정 script로 전환할 수 있다.
예를 들어 database의 vendor 이름 (hsqldb, h2, oracle, mysql, postgresql 등)으로 설정하도록 선택할 수 있다.
default로 SQL database initialization은 embedded in-memory database를 사용할 때만 수행된다.
유형에 관계 없이 SQL database를 항상 초기화하려면 spring.sql.init.mode를 always로 설정한다.
# always, never, embedded
spring.sql.init.mode=always
마찬가지로 initialization을 비활성화하려면 spring.sql.init.mode를 never로 설정한다.
default로 Spring Boot는 script 기반 database initializer의 fail-fast 기능을 활성화한다.
즉 script로 인해 exception이 발생하면 application이 시작되지 않는다.
spring.sql.init.continue-on-error를 설정하여 해당 설정을 조정할 수 있다.
Script 기반 DataSource initialization은 default로 JPA EntityManagerFactory bean이 생성되기 전에 수행된다.
schema.sql을 사용하여 JPA -managed entity들에 대한 scheam를 생성할 수 있고 data.sql을 사용하여 이를 채울 수 있다.
multi datasource initialization 기술을 사용하는 것을 권장하지 않지만 script 기반 DataSource initialization이 Hibernate에 의해 수행된 schema 생성을 기반으로 처리되길 원하면 spring.jpa.defer-datasource-initialization을 true로 설정하면 된다.
이는 EntityManagerFactory bean이 생성되고 initialization 될 때까지 data source initialization을 연기한다.
그 이후 schema.sql을 사용하여 Hibernate에 의해 처리된 schema 생성에 추가할 수 있고 data.sql을 사용하여 채울 수 있다.
Flyway 또는 Liquibase와 같은 상위 수준 database Migration Tool을 사용하는 경우 schema를 생성하고 initialization 하는데 단독으로 사용해야 한다.
Flyway 또는 Liquibase와 함께 basic schema.sql 및 data.sql script를 사용하는 것은 권장되지 않으며 향후 release에서 지원이 제거된다.
Initialize a Database Using Batch Database
Spring Batch를 사용하는 경우 가장 널리 사용되는 database platform용 SQL initialization script도 함께 미리 package로 제공된다.
Spring Boot는 database type을 감지하고 시작 시 해당 script를 실행할 수 있다.
embedded database를 사용하는 경우 default로 이 작업이 수행된다.
다음처럼 설정하여 모든 database type에 대해 활성화할 수도 있다.
# always, never, embedded
spring.batch.jdbc.initialize-schema=always
never로 설정하면 비활성화된다.
Use a Higher-level Database Migration Tool
Spring Boot는 두 가지 상위 수준 migration tool인 Flyway와 Liquibase를 지원한다.
이와 관련한 자세한 설명이 spring boot documentation에 있으나 여기에선 생략한다.
Depend Upon an Initialized Database
application context refresh의 일부로 application이 시작되는 동안 database initialization이 수행된다.
시작하는 동안 초기화된 database를 access 할 수 있도록 database initializer로 동작하는 bean과 해당 database를 필요로 하는 bean이 자동으로 탐지되어 적절히 동작하며 또한 이러한 bean에 대한 추가 감지를 구성할 수도 있다.