특정 컬럼들에 대해 위와 같은 예외가 발생하고 있었다.
서버는 정상 실행되며 ddl-auto : create-drop
으로 하여금 테이블이 잘 생성되는지 테스트 중이었다.
세부적으로 보기 위해 서버를 실행시켜놓고 해당 테이블의 키를 조회했는데 다음과 같은 중복 상황이 나왔다.
@Entity
@Table(
name = "post",
indexes = @Index(name = "idx_post_url", columnList = "postUrl")
)
public class Post extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "post_id")
private Long id;
...
@Column(unique = true, nullable = false)
private String postUrl;
더 문제를 확인해보니 서버를 끄게 되면 테이블들이 날라가야하는데 @Table(name = ...)
으로 지정한 테이블들이 drop이 되지 않았고 당연하게도 key에 대한 정보들도 남아있게 되었다.
이 상태에서 create를 다시 할 때 중복 문제가 나타난 것으로 보인다.
Hibernate
가 기본적으로 엔티티 클래스명을 테이블명으로 사용하지만, @Table(name = "user_table")처럼 직접 테이블명을 지정하면 Hibernate 내부적으로 관리하는 메타데이터가 달라질 수 있다는 것을 알게 되었다.
Hibernate가 DROP TABLE user_table을 실행하기 전에 다른 FK(외래 키) 제약 조건이 먼저 삭제되지 않으면 테이블 삭제가 실패할 수 있다.
특히 orphanRemoval = true가 설정된 관계가 많다면, Hibernate가 FK 삭제 순서를 잘못 처리하면서 테이블 삭제에 실패할 가능성이 있다.
ddl-auto: create-drop
이 실행될 때, Hibernate가 해당 테이블이 존재하지 않는다고 판단하여 DROP을 건너뛰는 경우 발생한다.
jpa:
hibernate:
ddl-auto: create-drop # 애플리케이션 실행 시 기존 테이블을 삭제하고 새로 생성 (데이터 초기화)
properties:
hibernate:
hbm2ddl.drop-cascade: true # Hibernate가 테이블 삭제 시 FK도 함께 삭제하도록 설정
order_updates: true
order_inserts: true
show_sql: true # 실행되는 SQL 쿼리를 콘솔에 출력
format_sql: true # SQL 쿼리를 가독성 좋게 포맷팅하여 출력
default_batch_fetch_size: 100 # 여러 개의 데이터를 한 번에 조회할 때 Batch 크기 설정 (성능 최적화)
위와 같이 hbm2ddl.drop-cascade: true
를 설정하여 해결했다.