트러블슈팅

Jenkins나 Spring Boot에서 Test 시, liquibase 외래키 참조 에러

MJ.Lee 2024. 1. 10. 10:59

문제

Test 코드를 돌리거나, Jenkins에서 Test를 실행할 때 data.xml 관련해서 아래와 같은 에러가 났다.

product 테이블에 product_code컬럼에 '상품 코드' 값을 넣으려고 하는데, '상품 코드' 값이 product_code 테이블에 존재하지 않는다는 의미다.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/linecorp/ladb/oacms/sd/sync/config/LiquibaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set config/liquibase/changelog/20240109141149_data.xml::1704777564021-3::user (generated):

Reason: liquibase.exception.DatabaseException: Referential integrity constraint violation: "fk_product: PUBLIC.""product"" FOREIGN KEY(""product_code"") REFERENCES PUBLIC.""product_code""(""code"") ('ABC123')";

SQL statement: INSERT INTO PUBLIC.product (id, product_name, product_code) VALUES (4, '상품명','상품 코드') [23506-197] [Failed SQL: (23506) INSERT INTO PUBLIC.product (id, product_name, product_code) VALUES (4, '상품명','상품 코드')]

 

하지만 product_code 테이블에는 '상품 코드' 값이 존재했다.

원인

data.xml에 있는 data를 insert할 때 일어나는 외래키 관련 에러이다.

외래키 참조가 걸려있는 product_code 테이블에 있는 데이터보다, product 테이블의 데이터를 먼저 insert하면서 발생된다.

 

하지만 data.xml에 있는 모든 코드를 순서에 맞게 정렬하려면 시간이 너무 오래 걸린다.

해결

아래와 같이 임시로 외래키 참조 체크를 풀어주는 코드를 data.xml에 추가하면 된다.

data.xml에서 changeSet 맨 앞과 맨 뒤에 아래 코드를 추가해준다.

 

맨 앞에는 SET FOREIGN_KEY_CHECKS=0; 으로 외래키 제한을 풀어준다는 의미이다.

id는 data.xml에서 다른 changeSet에서 사용하고 있는 id를 참조해 맨 앞은 0, 맨 뒤는 999로 하면 된다.

    <changeSet author="LADB" id="1704777564021-0">
        <sql>SET FOREIGN_KEY_CHECKS=0;</sql>
    </changeSet>

 

 

맨 뒤는 SET FOREIGN_KEY_CHECKS=1; 로 외래키 제한을 사용한다는 의미이다.