본문 바로가기
Skills/Spring

스프링부트 테스트 시, JPA와 SQL INIT 충돌 이슈

by Hoseok 2023. 4. 30.
728x90
반응형

마지막 통합테스트만이 남았다.

 

테스트의 편의를 위해 insert문으로 작성한 sql 스크립트문을 실행시킨다면,

테스트 코드 안에서 dummy 데이터를 만들어줄 필요 없이 쉽게 테스트를 할 수 있겠다고 생각했다.

 

그러나 문제가 발생했는데..!

 

ddl-auto와 data.sql을 혼합하는 방식

 

첫 번째로 시도한 설정은 ddl-auto와 data.sql을 혼합하는 방식이다.

 

application.yml 설정

 

ddl-auto를 create로 해서 table들을 다 생성한 뒤, 만들어준 data.sql을 실행시킨다면

문제없이 더미데이터를 사용할 수 있을 거라고 생각했지만...

 

 

dataSourceScriptDatabaseInitializer가 bean에 생성되는 데 실패했다는 에러가 뜬다.

 

더 자세한 이유를 찾아보니,

 

user테이블을 못 찾았다는 뜻이다.

 

왜 user테이블을 못 찾았을까, 생각하며 원인을 구글링하다 보니, 다음과 같은 이유를 찾을 수 있었다.

 

스프링부트 2.5 이전에는 위의 설정으로 문제없이 사용할 수 있었지만, 

 

스프링부트 2.5 이후 다음과 같은 내용이 추가되었다.

 

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 버전부터는 Hibernate가 초기화되기 전에 data.sql이 먼저 실행된다는 것이고,

Hibernate로 schema를 먼저 만들고 싶으면, spring.jpa.defer-datasource-initialization = true로 설정하면 된다고 설명하고 있다.

 

그리고 database 초기화 기술들을 믹싱하는 것은 추천하지 않는다고 되어있다.

 

그래도 일단 해보자는 마음으로

 

application.yml을 다시 설정하고 테스트를 다시 해보니

 

또 다시 실패했다.

 

원인은,

 

즉, 참조 무결성 제약 조건을 위반했다는 의미이다.

 

구체적인 이유로는 user_tb가 foreign key인 rate_id를 참조하려고 했지만 실패했다는 것인데,

단방향 mapping을 해놓은 탓에 찾지 못하는 이유였다.

하지만 단방향 mapping을 사용하지 않는다는 전략으로 모든 코드를 짜놓았기 때문에,

양방향 mapping으로 바꿔보았지만 대신에 엄청나게 많은 연관된 코드 수정이 필요하다는 문제가 발생했다.

 

그래서 이 방법은 포기했다.

 

Schema도 sql 스크립트문으로 생성하는 방식

 

두 번째로 시도한 방법은, Schema도 sql 스크립트문으로 생성하는 방식이다.

 

그러나,

 

 

몇 개는 성공하고 몇개는 실패하는 식이였는데,

 

실패한 테스트를 찾아보니

 

블랙리스트가 추가되는 insert문이 정확히 날아가고

insert가 되었지만

 

삭제하기 위해 select하는 과정에서 유저를 못 찾는다???

 

신기하게도 ddl-auto: create 일 때는 테스트가 잘 통과한다.

결론

결론적으로 jpa와 sql init 설정이 혼합되었을 때 내부에서 많은 충돌이 일어나는 듯하다는 결론을 내릴 수 밖에 없었고, 스프링에서 권유하듯이 mixing방법은 사용하지 않기로 했다.

 

추후 다른 방법을 찾는다면 블로그에 추가하겠습니다.

728x90
반응형