ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA 초기화 전략
    개발로그/오늘뭐먹지 프로젝트 2023. 1. 5. 18:23

     DB 초기화의 필요성을 느낀건 Review 기능을 개발하던 도중 테스트를 진행할 때였다. 다른게 아니라 Review 테이블의 PRIMARY KEY인 id 필드가 AUTO_INCREMENT로 설정되어있었는데, my_sql의 AUTO_INCREMENT의 설정은 만약 데이터를 삭제하더라도 무조건 다음 아이디를 뱉어내도록 설정되어 있었기에 findById 기능을 수행하던 도중 계속해서 문제가 터졌다. 이를 테스트 DB에 있는 Review 테이블을 아예 삭제했다가 다시 생성하면 정상적으로 동작하지 않을까 싶어서 구글링을 진행했고, 긴가민가 했던 내용도 많았기에 후에 까먹지 않기 위해 기록해두기로 결정했다.

     


    Hibernate 전략

     

    application.yml의 설정을 변경해서 수정할 수 있다. 

    spring.jpa.generate-ddl: 애플리케이션 시작시 스키마 초기화 여부를 지정하며 기본 값은 false이다.

    spring.jpa.hibernate.ddl-auto: DB 초기화 전략 옵션이다.

    none: DDL 핸들링 작업을 수행하지 않는다.

    create: 기존에 존재하는 스키마를 삭제하고 새로 생성한다.

    create-drop: 스키마를 생성하고 애플리케이션이 종료될 때 삭제한다.

    validate: 엔티티와 테이블이 정상적으로 매핑되어있는지 검증한다.

     

    인메모리 DB(ex. H2)를 사용하면 자동으로 create-drop 전략을 사용하지만 DB벤더(ex.mysql)을 사용하면 spring.jpa.generate-ddl=true를 설정해야 초기화가 진행된다.

     

     


     

    하지만 Hibernate 전략을 적용하자니  Review테이블에만 초기화를 적용하고 싶었는데, 전체 테이블에 적용되는게 문제였다. 이를 해결하기 위해 검색해보니 schema-sql을 classpath(test/resource/...)에 넣으면 자동으로 실행되어진다고 하여 다음과 같은 sql을 resource 폴더에 집어넣었다.

     

    -- schema.sql
    -- 테스트를 위해 review 테이블을 삭제 후 다시 생성합니다.
    
    DROP TABLE review;
    
    CREATE TABLE IF NOT EXISTS `what_i_should_eat_test`.`review` (
      `id` BIGINT NOT NULL AUTO_INCREMENT,
      `content` VARCHAR(255) NULL,
      `member_id` BIGINT NOT NULL,
      `store_id` BIGINT NOT NULL,
      PRIMARY KEY (`id`),
      INDEX `fk_review_member_idx` (`member_id` ASC) VISIBLE,
      INDEX `fk_review_store_idx` (`store_id` ASC) VISIBLE,
      CONSTRAINT `fk_review_member`
        FOREIGN KEY (`member_id`)
        REFERENCES `what_i_should_eat_test`.`member` (`id`)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
      CONSTRAINT `fk_review_store1`
        FOREIGN KEY (`store_id`)
        REFERENCES `what_i_should_eat_test`.`store` (`id`)
        ON DELETE CASCADE
        ON UPDATE CASCADE
    );

    이후에 findById 테스트를 실행시 정상적으로 계속해서 1번부터 아이디가 시작하는 것을 볼 수 있었다.

     

    * DML 스크립트는 data.sql, DDL 스크립트는 schema.sql 폴더 이름을 탐색한다

     

    * script를 통한 db 초기화와 Hibernate DDL 전략 초기화 방식 두 가지를 동시에 사용 할 순 없다. 따라서 spring.jpa.generate-ddl 옵션을 삭제하거나 false로 두고, spring.datasource.initialization-mode를 활성화해야한다.

     

    application.yml

    '개발로그 > 오늘뭐먹지 프로젝트' 카테고리의 다른 글

    Selenium을 이용한 크롤링  (1) 2022.12.23
    구조 리팩토링 - 테스트 DB 분리, 메시지 분리  (2) 2022.10.19
    CI/CD  (1) 2022.04.06
    AWS 배포  (0) 2022.03.31
    메인 기능 구현 완료  (0) 2022.03.10

    댓글

Designed by Tistory.