JPA | primary key

DoItDev·2021년 11월 19일
0
post-thumbnail

Overview

PK(primary key)?

Note:

  • 기본 키(primary key)는 주 키 또는 프라이머리 키라고 하며, 관계형 데이터베이스에서 조(레코드)의 식별자로 이용하기에 가장 적합한 것을 관계 (테이블)마다 단 한 설계자에 의해 선택, 정의된 후보 키를 말한다.
  • 유일 키는 0~1개 이상의 속성의 집합으로 볼 수 있다.
  • 즉, 관계에 저장된 레코드를 고유하게 식별하는 후보 키 (=속성 또는 속성의 집합) 가운데, 설계자가 일반적으로 이용되어야한다고 정해 놓은 것을 가리킨다.

Number PK

jpa에서 pk이를 사용하기 위해서는 @Entity 를 사용을 해주어야 합니다.

엔티티 어노테이션을 사용을 할경우 강제적으로 id 값을 메핑을 하게 해줍니다.

그렇다면 pk 값은 어떤게 있을까 .. ?

일단 pk 값의 경우 UUID, number로 선언을 해줍니다.

보통의 pk 값의 경우 number 숫자 형태로 선언을 많이 해주기 때문에 number 기준으로 설명을 하려고 합니다.

Long, Integer 의 경우 mysql 기준으로는 bigint가 생성이 됩니다.

아마 오라클의 경우 Number 타입으로 생성이 됩니다.

아래의 코드 처럼 예제 도메인의 경우 long 으로 선언을 해준 후

@Id, @GeneratedValue 두 가지를 선언을 해주고 난뒤 PK 값을 선언을 해줍니다.

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "app_test")
public class TestDomain implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

@GeneratedValue 의 경우 기본키 생성 전략을 세팅할 수 있습니다.

AUTO , IDENTITY, SEQUENCE, TABLE 세팅 할 수 있는 값의 경우 4가지가 있는데 default 값의 경우 AUTO로 되어 있습니다.

  • AUTO

    • JPA에서 DB에 따라서 자동으로 생성해주는 옵션입니다.
    • 오라클의 경우 SEQ, Mysql의 경오 auto increment를 설정을 해줍니다.
  • IDENTITY

    • 기본키 생성을 데이터 베이스에 위임합니다.
    • JPA 가 테이블을 생성이 될 때 auto increment 로 생성을 해줍니다. (자동증가가 되는 것만 적용)
  • SEQUENCE

    • 시퀀스를 가지고 테이블을 만들어 줍니다. (시퀀스가 사용되는 db 면 가능)
    • @SequenceGenerator 어노테이션과 함께 도메인을 구성 합니다.
  • TABLE

    • 키 생성 테이블을 사용을해서 관리한다
    • 설명을 추가 하자면 시퀀스용 물리 테이블을 생성을 하는거라고 생각하면 됩니다
@SequenceGenerator(name = "appTestDomainSeq", allocationSize = 1, sequenceName = "app_test_domain_seq")
public class TestDomain implements Serializable {
}

위의 코드 처럼 클래스 위에 선언을 해줍니다.

속성의 경우 name, allocationSize, sequenceName 등.. 있습니다

  • name: java 사용할 seq 명
  • sequenceName: db 선언된 물리적인 명칭을 의미
  • allocationSize: 시퀀스가 증가된 사이즈
  • schema: 시퀀스가 존재하는 스키마

그 뒤에 ID 값을 선언을 해줍니다.

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE , generator = "appTestDomainSeq")
    private Long id;

하지만 오라클에서 인식이 안될 수 도 있어서 yml에 new_generator_mappings 을 선언을 해줍니다.

auto의 경우 적용해주시면 됩니다. sequnce의 경우 사용을 안해줘도 됩니다.

여러개의 db를 작동 해야하는 프로젝트의 경우 참고 해주세요

spring:
  jpa:
    properties:
      hibernate:
        id:
          new_generator_mappings: true

UUID PK

Note:

  • 의역하면 범용 고유 식별자 라는 의미가 된다
  • 소프트웨어 구축에 쓰이는 식별자 표준으로, 개방 소프트웨어 재단(OSF)이 분산 컴퓨팅 환경(DCE)의 일부로 표준화하였다.
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "t_student")
public class Student extends BaseEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    @Embedded
    private Name name;

    @Builder
    public Student(String firstName, String lastName) {
        this.name = Name.builder()
                .firstName(firstName)
                .lastName(lastName)
                .build();
    }

}

기본적인 UUID로 ID 값을 생성을 하면 BINARY(255)로 생성이 된다

JPA에서 아래와 같이 DDL 를 만들어서 테이블을 만들어 준다

화면 캡처 2021-11-18 154928

그렇게 만들어진 테이블에 데이터를 저장 및 불러오는 것을 테스트를 해보다가 발견을 하였는데 id 값으로 조회를 할때 조회가 되지 않고 null로 가지고 있었다.

UUID 에러의 원인 해결

그렇게 검색을 해보니 위와 같은 문제를 가진 개발자분들이 존재를 했고 길이를 변경을 하게 되었다

위의 도메인 코드에서

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(columnDefinition = "BINARY(16)")
    private UUID id;

화면 캡처 2021-11-19 090916

ID 부분의 길이를 조정 후 검색을 해보니 정확히 조회가 되는 것을 보았다.

profile
Back-End Engineer

0개의 댓글