스프링부트 2.5+, Hibernate 사용시 DB 초기화 이슈
스프링부트 버전업에 의한 이슈 정리
🚨 문제
학습 프로젝트 진행 중 발견한 이슈이다.
Hiberate
를 사용하고 있었음- 스프링부트 버전 2.4 대에서 2.5+ 이상으로 버전업
data.sql
이 아래와 같은 메시지와 함께 정상동작하지 않음
🚧 원인
스프링부트 📜 릴리즈노트 에서 찾았다.
- Hibernate and data.sql
By default, data.sql scripts are now run before Hibernate is initialized.
This aligns the behavior of basic script-based initialization with that of Flyway and Liquibase.
If you want to use data.sql to populate a schema created by Hibernate, set spring.jpa.defer-datasource-initialization to true.
While mixing database initialization technologies is not recommended, this will also allow you to use a schema.sql script to build upon a Hibernate-created schema before it’s populated via data.sql.
대략 스프링부트 2.5부터는 data.sql
이 Hibernate
가 실행하는 ddl-auto
보다 먼저 실행된다는 것 같다.
따라서 기존과 같이 사용하고 싶다면 spring.jpa.defer-datasource-initialization=true
옵션을 추가하라고 한다.
실제로 이것이 문제인게 맞는지 우선 버전을 변경해 테스트해보았다.
우선 데모 프로젝트를 2.4.3
버전으로 생성했다.
의존성은 아주 간단하게 web
, data-jpa
, h2
만 추가했다.
그리고 application.yaml
파일을 다음과 같이 설정했다.
# file: 'application.yaml'
spring:
h2:
console:
enabled: true
settings:
web-allow-others: true
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
jpa:
properties:
hibernate:
format_sql: true
hibernate:
ddl-auto: create-drop
그리고 Hibernate
가 테이블을 생성하도록 다음과 같이 간단한 엔티티 클래스를 작성했다.
@Entity
public class Member implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
}
마지막으로 Hibernate
가 생성한 테이블에 삽입될 데이터를 resources/data.sql
에 추가했다.
-- file: 'resources/data.sql'
insert into member (name, age)
values ('name1', 10);
insert into member (name, age)
values ('name2', 10);
그리고 프로젝트를 실행하고 localhost:8080/h2-console
로 접근하여 테이블이 정상적으로 생성되었는지, 데이터가 정상적으로 삽입되었는지를 확인했다.
버전을 내려서 진행하니 정상적으로 동작함을 확인했다.
✅ 해결
2.4대에서 2.5+이상의 버전으로 변경 할 경우 옵션을 줘야한다고 하니 데모 프로젝트의 스프링부트 버전을 2.6.1
로 변경하고, application.yaml
에 옵션을 추가했다.
# file: 'application.yaml'
spring:
h2:
console:
enabled: true
settings:
web-allow-others: true
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
jpa:
defer-datasource-initialization: true # 추가 !
properties:
hibernate:
format_sql: true
hibernate:
ddl-auto: create-drop
마찬가지로 프로젝트를 실행하고 localhost:8080/h2-console
로 접근하여 테이블이 정상적으로 생성되었는지, 데이터가 정상적으로 삽입되었는지를 확인했다.
아무런 문제 없이 정상적으로 동작함을 확인했다.