공유된 따라하기 · JPA

JPA 기본 메서드 실습 — Postman 으로 CRUD 완성하기

주의 : 이 실습은 조별 프로젝트 과제가 아닙니다. 개인 공부를 위한 것입니다. 이건 공부용!! 조별 프로젝트는 공부가 아닌 적용!!

대상 Menu 엔티티와 MenuRepository 를 만든 뒤, JpaRepository 가 제공하는 기본 메서드를 직접 호출해보고 싶은 사람

목표 data.sql 로 시드 데이터를 넣고, Postman 으로 save, findAll, findById, existsById, deleteById, count 를 호출해서 CRUD 를 완료한다

완성물 시드 데이터가 로드된 PostgreSQL 과, Postman Collection 으로 전체 CRUD 플로우를 실행할 수 있는 MenuController

  • 앞 편(JPA 추가하기)을 마친 상태여야 한다. Menu 엔티티, MenuRepository, MenuController(POST, GET) 가 이미 존재한다.
  • Postman 이 설치되어 있어야 한다.
  • application.yml 의 spring.sql.init.mode 설정이 아직 없거나 never 인 상태다.
  • data.sql 파일은 아직 없다.

STEP 1 / 7data.sql 로 시드 데이터 로드 설정

0개 완료 · 7개 남음

  1. 애플리케이션 시작 시점에 미리 데이터를 넣기 위해 data.sql 파일을 사용한다. Spring Boot 는 src/main/resources 폴더에 있는 data.sql 파일을 자동으로 실행한다.

    기본적으로 Spring Boot 는 data.sql 이 JPA(Hibernate)의 DDL 실행 이후에 실행되도록 설정되어 있지 않다. 즉, data.sql 이 테이블 생성 전에 실행되어 Table "menus" does not exist 오류가 발생할 수 있다. 이를 방지하기 위해 spring.jpa.defer-datasource-initialization: true 설정을 명시적으로 추가해야 한다. 이 설정이 JPA 기반의 DDL(테이블 생성/갱신)이 완료된 이후에 data.sql 이 실행되도록 순서를 보장한다.

    이 설정 방법은 1-2에 설명되어 있다.

    1-1. data.sql 만들기

    파일: src/main/resources/data.sql

    -- 시드 데이터: 애플리케이션 시작 시 한 번만 실행되도록 가정
    -- 재시작 시 중복 삽입을 방지하려면 아래 DELETE 문을 주석 해제하거나,
    -- 애플리케이션 시작 전 매번 실행하는 스크립트로 관리한다.
    -- DELETE FROM menus;
    
    INSERT INTO menus (kor_name, eng_name, price) VALUES ('아메리카노', 'Americano', 4500);
    INSERT INTO menus (kor_name, eng_name, price) VALUES ('라떼', 'Latte', 5000);
    INSERT INTO menus (kor_name, eng_name, price) VALUES ('카푸치노', 'Cappuccino', 5200);

    1-2. application.yml 수정

    파일: src/main/resources/application.yml

    spring 블록 아래에 sql 설정을 추가한다.

    spring:
      datasource:
        url: jdbc:postgresql://cloud.newlecture.com:5441/ncafedb
        username: ncafe
        password: your_password_here
        driver-class-name: org.postgresql.Driver
      jpa:
        hibernate:
          ddl-auto: update
        show-sql: true
        properties:
          hibernate:
            format_sql: true
      sql:
        init:
          # JPA(Hibernate)가 테이블을 만든 뒤, data.sql을 실행하도록 설정
          mode: always

    참고: spring.sql.init.mode 값의 의미

    • always: 애플리케이션이 시작될 때마다 data.sql 을 실행한다.
    • embedded: 내장 데이터베이스(H2, HSQLDB 등)에서만 실행한다.
    • never: 실행하지 않는다.

    JPA 와 함께 사용할 때 always 로 설정하면, Hibernate 가 ddl-auto 로 테이블을 생성/갱신한 이후에 data.sql 이 실행된다.

    1-3. 애플리케이션 재시작 및 확인

    ./gradlew bootRun

    Windows 는 gradlew.bat bootRun

    ✅ 확인

    • 터미널 로그에 Hibernate: create table menus (...) 또는 alter table 문장이 보인다.
    • 그 직후 INSERT INTO menus ... SQL 문장이 3번 출력된다.
    • show-sql: true 설정 덕분에 콘솔에 INSERT 문장이 보인다.

    🎓 newlec 쌤의 코멘트

    spring.sql.init.mode: always 는 개발 환경에서 매우 유용하다. 하지만 주의할 점이 있다. data.sql 에 INSERT 문만 있으면, 애플리케이션을 재시작할 때마다 데이터가 중복으로 삽입된다.

    이를 방지하기 위한 방법으로는 data.sql 상단에 DELETE FROM menus; 를 주석해두고 필요할 때 활성화하는 방법이 있다. 하지만 이 경우 매번 파일을 수정해야 한다.

    더 나은 방법은 data.sql 대신 schema.sql 과 data.sql 을 분리하거나, Flyway/Liquid 같은 마이그레이션 도구를 사용하는 것이다. 하지만 이 실습에서는 간단함을 위해 data.sql 상단에 DELETE FROM menus; 를 주석 처리해두고, 데이터 초기화가 필요할 때 주석을 해제하는 방식으로 진행한다.

    JPA 와 SQL 초기화 스크립트의 실행 순서는 항상 JPA(DDL) → SQL(INSERT) 이다. spring.jpa.defer-datasource-initialization: true 를 설정하면 이 순서가 보장된다. Spring Boot 2.5 이후에는 기본적으로 이 순서가 보장되지만, 명시적으로 설정하는 것이 안전하다.

    ❌ 자주 하는 실수

    증상 원인 해결
    Table "menus" does not exist data.sql 이 테이블 생성 전에 실행됨 application.yml 에 spring.jpa.defer-datasource-initialization: true 추가
    Duplicate key value violates unique constraint 재시작 시 중복 INSERT data.sql 상단에 DELETE FROM menus; 주석 해제 후 재실행
    SQL syntax error data.sql 에 불필요한 공백이나 BOM 문자 파일 인코딩을 UTF-8 (BOM 없음) 으로 변경

    📝 이 단계의 핵심

    • spring.sql.init.mode: always 로 data.sql 을 항상 실행한다.
    • JPA 테이블 생성 후 data.sql 이 실행되도록 defer-datasource-initialization: true 를 권장한다.

이 주소는 글의 저작자가 공개한 링크입니다. 뉴렉처 스터디의 다른 자료는 로그인 후 볼 수 있어요.