Programming/JPA & Spring Data JPA 기초

05. 엔티티 식별자 생성 방식

JKROH 2023. 2. 23. 15:49
반응형
해당 강의는 코드 위주로 진행됩니다. 실질적인 객체 처리를 담당하는 코드는 링크에서 확인하시길 바랍니다.

* 식별자 생성 방식

  • 직접 할당 방식
  • 식별 칼럼 방식
  • 시퀀스 사용 방식
  • 테이블 사용 방식

 

* 직적 생성 방식

- @Id 설정 대상에 직접 값 설정

  • 이메일, 주문 번호 등 사용자가 입력한 값이나 규칙에 따라 식별자를 생성할 때 해당 방식을 사용한다.
  • 저장하기 전에, 보통은 생성 시점에 생성자를 통해 전달한다.
  • Hotel 클래스에서 확인할 수 있다.
  • Hotel 객체를 생성하는 시점에 생성자를 통해 Hotel의 id를 전달하고 persist를 진행한다.

 

* 식별 칼럼 방식

- DB 식별 칼럼에 매핑

  • MySQL의 자동 증가 칼럼과 같은 DB가 식별자를 자동으로 생성하는 칼럼에 매핑할 때 사용한다.
  • DB가 식별자를 생성하므로 객체 생성시에 식별값을 설정하지 않는다.
  • 보통 @Id에 붙은 대상에 추가로 @GeneratedValue(strategy = GenarationType.IDENTITY)를 붙여서 설정한다.
  • DB에 실제로 INSERT를 해야 식별자가 생성되기 때문에 EntityManager#persist()를 호출하는 시점에 INSERT 쿼리를 실행한다.
  • persist()를 실행할 때 객체에 식별자의 값이 할당된다.

- 식별 칼럼 방식 예시

  • Review 클래스, MainNative 클래스에서 확인할 수 있다.
  • 생성자에 식별자인 long id가 없음을 확인할 수 있다. 즉, 객체를 생성할 때 식별자를 설정하지 않는다.
  • entityManager.persist(review);를 호출하는 시점에 ISERT쿼리를 바로 실행한다(commit 시점이 아니라).
  • persist() 이후에 review.getId();를 통해 식별자를 사용할 수 있다.

 

* 시퀀스 사용 방식

- 시퀀스를 사용해서 식별자 생성

  • 오라클 시퀀스 등을 사용해서 식별자를 생성하는 방식이다.
  • JPA가 시퀀스 호출, 호출 결과를 식별자 대상에 할당 등을 모두 처리한다.
  • 객체를 생성하는 시점에 식별값을 설정하지 않는다.
  • @SequecneGenerator와 @GeneratedValue 모두 설정해야 한다.
    • @SequecneGenerator로 시퀀스 생성기를 설정한다.
    • @GeneratedValue의 generator 로 시퀀스 생성기를 지정한다.
  • EntityManaager#persist() 호출 시점에 시퀀스를 사용한다.
    • persist()를 실행할 때 객체에 식별자 값이 할당된다.
    • INSERT 쿼리를 실행하지 않는다. 식별 칼럼 방식은 DB가 생성한 값을 식별자로 사용하기 때문에 INSERT를 반드시 실행해야 하지만, 시퀀스 방식은 시퀀스에서 만든 식별자만 사용하면 되기 때문이다.

- 시퀀스 사용 방식 예시

  • ActivityLog 클래스와 MainSequence 클래스에서 확인할 수 있다. 
  • @SequecneGenerator의 name과 @GeneratedValue의 generator의 이름은 같은 값을 사용한다.
  • @SequecneGenerator 도 schema와 catalog를 지정할 수 있다
  • allocationSize 는 1로 지정해야 한다. 다른 값으로 지정하면 식별자가 중복 생성되는 문제가 발생하게 된다.
  • 생성자에 식별자인 long id가 없음을 확인할 수 있다. 즉, 객체를 생성할 때 식별자를 설정하지 않는다.
  • entityManager.persist(log);를 호출하는 시점에 시퀀스로 식별자를 구한다.
  • 트랜잭션을 commit하는 시점에 INSERT쿼리를 실행한다.

 

* 테이블 사용 방식

- 테이블을 시퀀스처럼 사용

  • 테이블에 엔티티를 위한 key를 보관한다.
  • persist()시점에 key를 가져와서 식별자로 사용한다.
  • @TableGenerator와 @GeneratedValue 모두 설정해야 한다.
    • @TableGenerator로 테이블 생성기를 설정한다.
    • @GeneratedValue의 generator 로 테이블 생성기를 지정한다.
  • EntityManager#persist()를 호출하는 시점에 테이블을 사용해서 식별자를 구하고 Entity에 할당한다.
  • 이 때, INSERT 쿼리는 실행하지 않는다.
  • 사용 빈도가 낮다.

- 테이블 사용 방식 예시

  • ddl.sql 파일과 AccessLog 클래스, MainTableGenId 클래스에서 확인할 수 있다.
  • 칼럼이 2개 있는 테이블이 필요하다.
    • 하나의 칼럼은 Entity를 구분하기 위한 이름을 보관한다.
    • 다른 하나의 칼럼은 식별자를 보관한다.
  • @TableGenerator
    • name 은 테이블의 이름이다.
    • table 은 id를 생성할 때 사용할 테이블 이름을 지정한다.
    • pkColumnName 은 Entity 이름을 보관할 칼럼이다.
    • pkColumnValue는 Entity의 이름이다.
    • valueColumnName 은 다음 식별자를 구할 때 사용할 칼럼이다.
    • initalVlaue는 보통 0으로 지정하고 다음 식별자는 1부터 생성된다.
    • allocationSize는 마찬가지로 1로 설정한다.

 

* 정리

  • 식별자 생성방식
    • 직접 할당 
    • 식별 칼럼 방식 : 저장 시점에 INSERT 쿼리 실행
    • 시퀀스 사용 방식 : 저장 시점에 시퀀스 사용해서 식별자 생성
    • 테이블 저장 방식 : 저장 시점에 테이블 사용해서 식별자 생성. 사용 빈도는 낮다.
반응형