Spring/JPA

UUID를 기본키(PK)로 갖는 엔티티의 외래키(FK)로 참조하는 경우, COLLATE 설정 주의 (Error executing DDL)

흑시바 2025. 6. 28. 23:46

문제

Spring, MariaDB 환경에서 기본 키(PK)를 UUID로 갖는 엔티티를 참조하는 엔티티를 만들고, Spring Data JPA의 ddl-auto 옵션을 update로 가져갔는데 런타임 과정에서 계속해서 오류가 발생했다.

 

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    alter table if exists shiba_holic_log
       add constraint FKh8d0anhgjweycfgevwhybkpl2 
       foreign key (room_id) 
       references room (id)" via JDBC [(conn=54) Can't create table `shiba`.`shiba_holic_log` (errno: 150 "Foreign key constraint is incorrectly formed")]

 

키 타입이 달라서 문제인가 확인했으나, MariaDB에서 PK를 가지는 Room의 ID와 동일한 타입 VARCHAR(36)을 가지고 있었다.

 

런타임을 몇 차례 시도한 끝에 포기하고 데이터 베이스에 직접 외래 키 설정을 했는데도, 타입이 달라서 생성을 할 수 없다는 메시지를 받았다.

원인

데이터베이스에 기본으로 설정된 COLLATE와 JPA가 자동으로 생성해 주는 COLLATE가 달라서 문제가 발생한 것이었다. 예를 들면, 아래 이미지와 같이 데이터베이스를 생성할 때 설정하는  COLLATE 값이 다른 것이다.

 

해결

UUID 키를 설정할 때, 아래와 같이 데이터베이스에 기본적으로 설정된 방식대로 따르도록 설정해 주었더니 ddl-auto 설정에 따라 자동으로 생성이 정상적으로 되었다.

 

@Entity
public class ShibaHolic {

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
    @JdbcTypeCode(SqlTypes.VARCHAR)
    @Column(name = "id", columnDefinition = "VARCHAR(36) COLLATE utf8mb4_general_ci")
    private UUID id;
}

 

Properties 설정을 통해 관련 COLLATE를 통일시킬 수도 있다고 한다. 개발하다가 동일한 상황에서 columDefinition 설정을 하지 않아, 오류를 발생하지 않도록 다음과 같은 설정 방식도 고려해 보도록 하자.

 

spring.jpa.properties.hibernate.dialect.storage_engine=innodb
spring.jpa.properties.hibernate.connection.characterEncoding=utf8mb4
spring.jpa.properties.hibernate.connection.collation=utf8mb4_general_ci

추가 지식

COLLATE 란?

COLLATE는 MySQL과 같은 데이터베이스에서 문자열 데이터를 비교하고 정렬하는 방식을 정의하는 정렬 규칙(Collation)을 의미한다. 즉, 문자열 데이터를 저장하거나 검색할 때, 대소문자 구분 여부, 언어별 특수 문자 처리 방식 등을 결정한다.