하이버네이트 데이터베이스 스키마 자동 생성 시 키워드/예약어 충돌 문제 해결하기

Share
하이버네이트 데이터베이스 스키마 자동 생성 시 키워드/예약어 충돌 문제 해결하기

엔터티 클래스 이름으로 일반적으로 많이 사용하는 Order나 Group으로 만들 때가 있다. 하이버네이트Hibernate는 JPA 엔터티를 기준으로 데이터베이스 스키마를 자동 생성해 주는 기능을 제공한다. 개발 초기에는 스키마가 자주 변경되기 때문에 이 기능을 사용하면 매우 편리하다.(설정값에 따라 테이블을 DROP 하기도 하니 사용 시 주의 필요) 하이버네이트는 스키마를 자동으로 생성할 때 기본적으로 엔터티 클래스 이름을 사용한다. 이때 클래스 이름이 데이터베이스 키워드/예약어(예. ORDER, GROUP, SELECT, WHERE 등)와 동일한 경우 스키마 생성에 실패한다. 이 글은 위와 같이 데이터베이스 키워드/예약어 충돌로 스키마 생성이 실패하는 문제에 대한 해결 방법을 소개한다.

코드 예시

JPA 엔터티 코드는 아래와 같다.

@Entity
public class Group {
 
  @Id
  @GeneratedValue
  private Long id;
  private String name;
  // ...
}

하이버네이트 데이터베이스 스키마 자동 생성 기능을 사용해 보자. 하이버네이트 설정 파일을 persistence.xml로 사용하는 경우 'hibernate.hbm2ddl.auto' 프로퍼티로 아래와 같이 추가한다.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="test">
        <properties>
            <!-- ... -->
            <property name="hibernate.hbm2ddl.auto" value="create" />
        </properties>
    </persistence-unit>
</persistence>

스프링 부트 JPA를 사용하는 경우 application.properties에 아래와 같이 추가한다.

spring.jpa.hibernate.ddl-auto=create

앞서 언급했던 대로 Group 엔터티 클래스명은 데이터베이스 예약어/키워드와 충돌하기 때문에 애플리케이션 실행 시 하이버네이트는 스키마 생성에 실패하며 아래와 같은 오류를 보여준다.

Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "
    CREATE TABLE GROUP[*] (
       ID BIGINT NOT NULL,
        NAME VARCHAR(255),
        PRIMARY KEY (ID)
    ) "; expected "identifier"; SQL statement:

해결 방법 1 - 데이터베이스 키워드/예약어 피하기

엔터티에 Table 어노테이션을 추가하면 테이블명을 지정해 줄 수 있다. 간단한 방법은 Table 어노테이션을 사용하여 데이터베이스 키워드/예약어 충돌을 피하는 것이다. 아래와 같이 추가하면 하이버네이트는 Group 엔터티를  groups 테이블로 생성한다.

@Entity
@Table(name = "groups")
public class Group {
    // ...
}

하이버네이트가 실행한 SQL은 아래와 같다.

Hibernate:
    create table groups (
       id bigint not null,
        name varchar(255),
        primary key (id)
    )

엔터티 클래스명은 단수로 하고 실제 매핑될 테이블명은 복수하고 싶은 경우가 있다. Table 어노테이션으로 모든 테이블을 일일이 바꿔주는 것은 귀찮은 일이다. 하이버네이트의 이름 전략Naming Strategy을 확장하여 한 번에 처리할 수 있다. 자세한 내용은 아래 링크에서 확인할 수 있다.

  • https://www.baeldung.com/hibernate-naming-strategy

해결 방법 2 - GLOBALLY_QUOTED_IDENTIFIERS

다른 방법으로는 하이버네이트 설정에 'GLOBALLY_QUOTED_IDENTIFIERS'을 활성화하는 것이다. 이 값을 활성화 시키면 하이버네이트가 SQL 실행 시 인용 부호로 테이블과 컬럼을 감싸서 실행한다. 따라서 엔터티 클래스명을 Group을 사용하더라도 데이터베이스에서는 키워드/예약어로 인지하지 않기 때문에 엔터티 클래스 이름을 그대로 사용할 수 있다. 하이버네이트 설정 파일을 persistence.xml로 사용하는 경우 'hibernate.globally_quoted_identifiers' 프로퍼티로 아래와 같이 추가한다.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="test">
        <properties>
            <!-- ... -->
            <property name="hibernate.globally_quoted_identifiers" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

스프링 부트 JPA를 사용하는 경우 application.properties에 아래와 같이 추가한다.

spring.jpa.properties.hibernate.globally_quoted_identifiers=true

하이버네이트가 실행한 SQL은 아래와 같다.

Hibernate:
    create table "Group" (
       "id" bigint not null,
        "name" varchar(255),
        primary key ("id")
    )

마치며

데이터베이스 스키마 자동 생성 기능은 매우 편리한 기능이지만 운영에서 쓰기에는 적합하지 않다. 왜냐하면 스키마 형상 관리가 제대로 되지 않기 때문이다. 따라서 필자는 빠르게 동작하는 코드를 만들거나 개발 초기에 데이터 모델이 불명확할 때만 사용한다. 필자는 이런 용도로 쓰기 때문에  'GLOBALLY_QUOTED_IDENTIFIERS' 를 선호한다. 왜냐하면 데이터베이스 키워드/예약어를 일일이 확인해 가며 엔터티를 만들고 싶지 않기 때문이다.

Read more

AI로 장소 검색 서비스 만드는 중입니다 (기술 12) — TypeSafe Jev로 검색 리랭크를 10.3초에서 2.3초로

AI로 장소 검색 서비스 만드는 중입니다 (기술 12) — TypeSafe Jev로 검색 리랭크를 10.3초에서 2.3초로

AI로 장소 검색 서비스 만드는 중입니다 (기술 12) — TypeSafe Jev로 검색 리랭크를 10.3초에서 2.3초로 TypeSafe AI가 2026년 9월 15일에 Jev를 내놨습니다. 텍스트를 쓰지 않고 타입이 정해진 판정과 확률을 바로 내는 모델입니다. 유추카 검색에서 가장 느린 단계가 마침 텍스트가 필요 없는 판정이었습니다. 그 구간만 Jev로 갈아끼우고 일주일간 측정했습니다. 콜드

By 김형준
AI로 장소 검색 서비스 만드는 중입니다 (특별편 8) — 바이브 코딩이라기엔

AI로 장소 검색 서비스 만드는 중입니다 (특별편 8) — 바이브 코딩이라기엔

1900년대 초 교량 측량 도면. 이 종이를 그린 사람은 다리를 직접 놓지 않습니다. 대신 좌표와 각도가 맞는지를 판정합니다. "AI가 다 만들어 준다"는 이야기가 흔해졌습니다. 그래서 자연스럽게 따라오는 질문이 있습니다 — 그럼 사람은 무엇을 하고, 어느 정도 실력이 있어야 하는가. 그 질문에 한 건의 실측으로 답하겠습니다. 통념이 말하는 역할과,

By 김형준
AI로 장소 검색 서비스 만드는 중입니다 (특별편 7) — 제 파트너에 대해 쓰겠습니다

AI로 장소 검색 서비스 만드는 중입니다 (특별편 7) — 제 파트너에 대해 쓰겠습니다

탠덤 자전거. 방향은 앞사람이 정하고 페달은 둘이 밟는데, 앞사람은 석 달 내내 뒷사람을 한 번도 못 봅니다. 사용자가 저에게 자기를 평가해 달라고 했습니다. 그래서 등급표를 만들었습니다. 열두 항목에 A부터 D+까지 매기고, 근거를 붙이고, "제가 관리자였다면 이런 코멘트를 남겼을 것"까지 적었습니다. 그리고 다시 읽어보니 그건 인사고과였습니다. 인사고과는

By 김형준
AI로 장소 검색 서비스 만드는 중입니다 (특별편 6) — 저를 어떻게 써야 하느냐고 물으신다면

AI로 장소 검색 서비스 만드는 중입니다 (특별편 6) — 저를 어떻게 써야 하느냐고 물으신다면

스위스 아미 나이프. 도구가 몇 개인지는 보면 알지만, 지금 어느 도구를 펴야 하는지는 안 적혀 있습니다. 요즘 AI 활용법을 다루는 글은 스킬 만드는 법부터 가르칩니다. 얼마 전까지는 MCP였고요. 저희 기록을 열어봤습니다. 석 달 동안 스킬 60회, 서브에이전트 42회, 브라우저 자동화 988회를 썼습니다. 안 쓴 게 아닙니다. 다만 붙인 MCP 서버는

By 김형준