@Entity 와 xxx.sql 중 어떤 쿼리가 우선순위를 가질까

Daniel·2025년 5월 19일

DataBase

목록 보기
4/5

들어가며

Spring Boot와 JPA를 사용하는 프로젝트에서 테이블 생성은 보통 두 가지 방식 중 하나로 이루어집니다.

  1. @Entity 어노테이션을 통해 JPA가 테이블을 자동 생성
  2. data.sql 또는 schema.sql 파일을 통해 SQL 문으로 직접 테이블을 생성

그런데 이 두 방식이 동시에 사용될 경우, 누가 테이블 생성을 먼저 담당하게 될까요?
만약 둘 다 같은 테이블을 정의하고 있다면 충돌이 발생하지 않을까요?
이번 글에서는 @Entityxxx.sql 간의 우선순위, 그리고 충돌 시 실제로 어떤 일이 벌어지는지를 정리해보겠습니다.

결론부터 말하면, JPA가 우선입니다.

Spring Boot 기본 설정에서는 Hibernate(JPA)가 테이블 생성을 먼저 수행하고, 그 이후에 xxx.sql 파일이 실행됩니다.
즉, @Entity가 먼저 실행되고 xxx.sql은 그 다음입니다.

각 방식의 동작 방식 정리

1. @Entity와 Hibernate의 테이블 생성

JPA는 @Entity로 정의된 클래스를 기반으로 테이블을 자동으로 생성하거나 업데이트합니다.
Spring Boot에서는 아래 설정을 통해 이 동작을 제어합니다:

spring.jpa.hibernate.ddl-auto=create | update | none | validate | create-drop
  • create: 애플리케이션 시작 시 테이블을 새로 생성
  • update: 기존 스키마를 유지하면서 엔티티 변경사항만 반영
  • validate: 스키마를 검증만 하고 생성/수정은 하지 않음
  • none: Hibernate는 아무런 스키마 작업을 하지 않음
  • create-drop: 시작 시 생성, 종료 시 삭제

2. xxx.sql (예: data.sql, schema.sql)

Spring Boot는 애플리케이션 시작 시 SQL 스크립트를 자동으로 실행합니다.
기본적으로 data.sqlHibernate 이후에 실행됩니다.

즉, @Entity를 통해 Hibernate가 먼저 테이블을 만들고,
그 뒤에 data.sql이 실행되어 데이터를 넣거나, 추가적인 작업을 수행하는 구조입니다.

충돌 상황에는 어떻게 될까?

// Java
@Entity
public class Member {
	;;
}
-- data.sql
CREATE TABLE member (...);

Hibernate가 먼저 member 테이블을 만들고 나면, data.sql의 CREATE TABLE 문은 이미 존재하는 테이블을 다시 만들려고 하기 때문에 오류가 발생합니다.
DB에 따라 "table already exists" 에러가 날 수 있습니다.

Hibernate는 테이블 생성, data.sql은 데이터 삽입만

-- data.sql
INSERT INTO member (id, name) VALUES (1, '홍길동');

이 경우는 정상적으로 작동합니다. Hibernate가 먼저 테이블을 만들고, data.sql이 초기 데이터를 넣습니다.

제어 방법 정리

Hibernate 비활성화, SQL만 사용하고 싶다면

spring.jpa.hibernate.ddl-auto=none
  • Hibernate의 스키마 생성을 완전히 비활성화
  • data.sql 또는 schema.sql에서 모든 테이블을 수동으로 작성해야 함
  • 특정 SQL 구문(JPA로 처리 불가한 기능 등)이 필요한 경우 유용

xxx.sql 실행을 막고 싶다면

spring.sql.init.mode=never
  • data.sql, schema.sql 실행을 막음
  • Hibernate만 스키마/데이터를 관리하게 됨

하이브리드 방식 (보통 이걸 많이 씀)

spring.jpa.hibernate.ddl-auto=update
spring.sql.init.mode=always
  • Hibernate가 테이블 생성 및 변경을 처리
  • data.sql은 초기 데이터만 삽입 (CREATE TABLE은 피해야 함)

모범 사례

  • 스키마 생성은 Hibernate(@Entity)에 맡기자
    → Java 코드와 DB 스키마가 일관성을 가질 수 있음

  • 데이터 초기화data.sql에 맡기자
    → INSERT만 넣고, 테이블 생성은 피하자

  • DDL은 한 쪽에서만 관리하자
    → Hibernate와 SQL 스크립트가 동시에 CREATE TABLE 하면 충돌 발생 가능성 큼

마무리

Spring Boot에서는 보통 Hibernate가 테이블 생성을 먼저 하고, xxx.sql이 뒤따라 실행됩니다.
이 순서를 이해하지 못하면 table already exists 같은 에러를 만나게 됩니다.

정리하자면:

목적권장 방식
테이블 생성@Entity + spring.jpa.hibernate.ddl-auto 설정
데이터 삽입data.sql 사용, 단 INSERT만 포함해야 함
SQL로만 전체 관리ddl-auto=none, SQL 파일로 CREATE 포함
SQL 완전 무시spring.sql.init.mode=never 설정

상황에 맞게 역할을 분리하고 충돌을 방지하는 설계를 해야할 것 같습니다.

profile
응애 나 애기 개발자

0개의 댓글