SPRING/JPA

[JPA] 상속 Table Per Class전략과 자동생성 키 @GeneratedValue의 Identity전략을 함께 사용할 수 없는 이유

Kishi 2024. 7. 11. 09:44

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)와 @GeneratedValue(strategy =GenerationType.IDENTITY)를 함께 사용할 수 없는 이유는 각 전략이 상호 충돌하기 때문이다.

 

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

  • 설명:
    • TABLE_PER_CLASS 전략은 각 엔티티 서브클래스마다 별도의 테이블을 생성하는 상속 전략. 즉, 상속 구조의 각 엔티티마다 고유한 테이블이 생성되고, 모든 상속된 필드가 그 테이블에 포함된다.
  • 구현:
    • 부모 클래스에 선언된 필드와 자식 클래스에 선언된 필드를 모두 포함하는 테이블이 각각의 자식 클래스에 대해 생성됩니다.
    • 각 테이블은 상속 구조 내에서 다른 테이블들과 중복된 필드를 가질 수 있습니다.

@GeneratedValue(strategy = GenerationType.IDENTITY)

  • 설명:
    • IDENTITY 전략은 데이터베이스의 자동 증가 필드를 사용하여 기본 키 값을 생성하는 전략. 주로 MySQL, SQL Server 등에서  사용됨
  • 동작 원리:
    • IDENTITY 전략은 각 엔티티 인스턴스가 삽입될 때 데이터베이스에서 자동으로 증가된 값을 가져옵니다.
    • 데이터베이스가 자동으로 값을 생성하기 때문에, 엔티티 매니저는 삽입 후에 생성된 값을 다시 조회해야 합니다.

왜 TABLE_PER_CLASS와 IDENTITY 전략을 함께 사용할 수 없는가?

  1. 테이블 생성 방식의 차이:
    • TABLE_PER_CLASS 전략은 각 엔티티마다 별도의 테이블을 생성합니다.
    • IDENTITY 전략은 각 테이블에 대한 고유의 자동 증가 컬럼을 필요로 합니다.
  2. JPA 구현체의 제한:
    • JPA 구현체(예: Hibernate)는 TABLE_PER_CLASS 전략을 사용할 때 부모 클래스와 자식 클래스 각각에 대한 테이블을 생성하고, 각각의 테이블에 대해 별도의 시퀀스나 ID 생성 전략을 설정해야 합니다.
    • IDENTITY 전략은 데이터베이스 레벨에서 ID 생성을 처리하기 때문에, 테이블 간에 일관된 시퀀스를 보장할 수 없습니다. 이는 TABLE_PER_CLASS 전략에서 여러 테이블이 존재하는 경우 충돌을 일으킬 수 있습니다.
  3. 자동 증가 필드와 상속 구조의 비호환성:
    • IDENTITY 전략은 특정 테이블에 종속적입니다. 상속 구조에서는 각 자식 클래스마다 별도의 테이블이 생성되므로, 하나의 일관된 자동 증가 전략을 적용할 수 없습니다.

 

결론

IDENTITY 전략은 단일 테이블에 대해 자동 증가 필드를 필요로 하지만,

TABLE_PER_CLASS 전략은 각 서브클래스마다 별도의 테이블을 생성하기 때문에 이 두 전략을 함께 사용할 수 없습니다.

 

이에 대한 해결법으로  시퀀스 기반의 ID생성 방법인 TABLE, SEQUENCE전략을 사용할 수 있다.

 @GeneratedValue(strategy = GenerationType.TABLE)
 @GeneratedValue(strategy = GenerationType.SEQUENCE)

 

'SPRING > JPA' 카테고리의 다른 글

[JPA] JPQL에서 '방언' 정의  (0) 2024.07.12
[JPA] FetchType.LAZY와 FetchType.EAGER  (0) 2024.07.10