ysk(0soo)
Lifealong
ysk(0soo)
전체 방문자
오늘
어제
  • 분류 전체보기 (238)
    • Java (50)
      • whiteship-java-study (11)
      • Java (28)
      • time (6)
    • Spring (68)
      • JPA (15)
      • Spring (1)
      • SpringBoot (1)
      • SpringMVC (6)
      • Spring Security (22)
      • Jdbc (1)
      • RestDocs (14)
      • log (6)
    • Kotlin (3)
    • Web (2)
      • nginx (1)
    • Database (14)
      • MySQL (5)
      • PostgreSQL (1)
      • SQL (1)
      • Redis (4)
    • C, C++ (0)
    • Git (1)
    • Docker (2)
    • Cloud (3)
      • AWS (3)
    • 도서, 강의 (0)
      • t5 (0)
    • 기타 (7)
      • 프로그래밍 (1)
    • 끄적끄적 (0)
    • CS (14)
      • 운영체제(OS) (2)
      • 자료구조(Data Structure) (9)
    • 하루한개 (12)
      • 우아한 테크코스-10분테코톡 (12)
    • 스터디 (12)
      • 클린 아키텍처- 로버트마틴 (2)
      • JPA 프로그래밍 스터디 (10)
    • 테스트 (34)
      • JUnit (19)
      • nGrinder (2)
      • JMeter (0)
    • Infra (3)
    • 프로그래머스 백엔드 데브코스 3기 (0)
    • 디자인 패턴 (3)
    • Issue (4)
    • system (1)
      • grafana (0)
      • Prometheus (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • github

공지사항

인기 글

태그

  • querydsl
  • 정규표현식
  • 트랜잭션
  • nginx basic auth
  • FilterSecurityInterceptor
  • node exporter basic auth
  • restdocs enum
  • scope value
  • DataJpaTest
  • 동등성
  • java
  • restdocs custom
  • VirtualThread Springboot
  • StructuredConcorrency
  • LocalDateTime
  • nGrinder
  • junit5
  • 동시성 제어
  • 동일성
  • jpa
  • AccessDecisionManager
  • 가상 스레드 예외 핸들링
  • tree
  • 인가(Authorization) 처리
  • AccessDecisionVoter 커스텀
  • AuthenticationException
  • mysql
  • 구조화된 동시성
  • 가상 스레드
  • UserDetailsService

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
ysk(0soo)

Lifealong

스터디/JPA 프로그래밍 스터디

JPA 프로그래밍 스터디 4장 정리

2022. 9. 13. 20:35

4 엔티티 매핑

4.1 @Entity

4.2 @Table

4.3 다양한 매핑 사용

4.4 데이터베이스 스키마 자동 생성

4.5 DDL 생성 기능

4.6 기본 키 매핑

4.7 필드와 컬럼 매핑 : 레퍼런스

JPA는 다양한 어노테이션을 지원한다. 
​
* 객체와 테이블 매핑 : @Entity, @Table
* 기본키 매핑 : @Id
* 필드와 컬럼 매핑 : @Column
* 연관관계 매핑 : @ManyToOne, @JoinColumn, @OneToMany ...

4.1 @Entity

관계형 데이터베이스의 테이블과 매핑할 클래스는 @Entity 어노테이션을 클래스 위에 필수로 붙여줘야 한다.

@Entity(name = "")
public class Member {
  ...
    
  public Member() {} // 또는 protected  
  
}

@Entity가 붙은 클래스는 JPA가 관리하게 되며 엔티티라 부른다

@Entity의 속성(어노테이션 필드)

  • name : JPA에서 사용할 엔티티 이름을 지정한다. 테이블의 이름을 지정하는 것이 아니다.
    • 기본 값은 "" 이며 설정하지 않으면 클래스 이름을 그대로 사용한다.
    • 기본 생성자가 필수이다(파라미터가 없는 public 생성자 또는 protected 생성자).
      • 왜? -> 리플렉션이나 프록시 기반 기술을 사용할 때는 기본 생성자가 필수이다.
        • private 기본 생성자는 상속받아서 구현 할 수 없기 때문이다.
        • 또한 지연 로딩을 사용할 때는 임시로 hibernate가 생성한 proxy 객체를 사용하는데, 이때 기본 생성자가 없거나 private 이면 프록시 패턴으로 객체를 만들 수 없다.
        • 읽어보면 좋다
        • 자바는 생성자가 없으면 기본 생성자를 자동으로 만들어 주는데, 만약 생성자를 하나 이상 만들면 기본생성자를 자동으로 만들지 않는다.
    • final 클래스, enum, interface, inner 클래스에는 @Entity 어노테이션을 사용할 수 없다.
    • 저장할 필드에 final을 사용하면 안된다.
      • JPA는 엔티티의 필드 변경과 변경감지로 값을 update 하기 때문.

4.2 @Table

@Table은 엔티티와 실제로 매핑할 테이블을 지정한다.

생략하면 매핑한 엔티티의 이름을 테이블로 사용한다.

@Entity(name = "")
@Table
public class Member {
  ...
    
  public Member() {} // 또는 protected  
  
}
​
@Target(TYPE)
@Retention(RUNTIME)
public @interface Table { // Table 어노테이션의 필드들
​
  String name() default "";
​
  String catalog() default "";
​
  String schema() default "";
​
  UniqueConstraint[] uniqueConstraints() default { };
​
  Index[] indexes() default {};
​
}

@Table의 속성(어노테이션 필드)

  • name : 매핑할 테이블의 이름을 지정한다. 생략하면 엔티티 이름을 사용한다.
  • catalog : catalog 기능이 있는 DB에서 catalog를 매핑한다.
    • 데이터베이스 카탈로그는 데이터베이스의 개체들에 대한 정의를 담고 있는 메타데이터들로 구성된 데이터베이스 내의 인스턴스이다. 기본 테이블, 뷰 테이블, 동의어(synonym)들, 값 범위들, 인덱스들, 사용자들, 사용자 그룹 등등과 같은 데이터베이스의 개체들이 저장된다.
  • schema : schema 기능이 있는 데이터베이스에서 schema를 매핑한다.
  • uniqueConstraints : DDL 생성 시에 유니크 제약조건을 만든다.
    • 2개 이상의 복합 유니크 제약조건도 만들 수 있다.
    • 이 기능은 스키마 자동 생성 기능을 사용해서 DDL을 만들때만 사용된다.
      • 스프링 부트에서는 properties 설정을 통해ddl-auto 옵션으로 자동으로 만들 때.
// uniqueConstaints 옵션 사용
@Entity
@Table(name="MEMBER", uniqueConstraints = {@UniqueConstraint( //추가 //**
        name = "NAME_AGE_UNIQUE",
        columnNames = {"NAME", "AGE"} )})
public class Member {
  
  private String name;
  
  private Integer age;
}

4.3 다양한 매핑 사용

회원 관리 프로그램에서 요구사항이 추가되었다.

  1. 회원은 일반 회원과 관리자로 구분해야 한다 -> 회원 테이블에 구분값 컬럼이 필요
  2. 회원가입과 수정일이 있어야 한다. -> 날짜 관련 컬럼이 필요
  3. 회원을 설명할 수 있는 필드가 있어야 한다. 이필드는 길이 제한이 있다 -> text 형식의 컬럼이 필요.
@Entity
@Table(name="MEMBER")
public class Member {
​
    @Id
    @Column(name = "ID")
    private String id;
​
    @Column(name = "NAME", nullable = false, length = 10) //추가 //**
    private String username;
​
    private Integer age;
​
    //=== 추가
    @Enumerated(EnumType.STRING)
    private RoleType roleType;
​
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;
​
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;
​
    @Lob
    private String description;
​
    @Transient
    private String temp;
}
​
public enum RoleType {
    ADMIN, USER
}
  • enum 타입을 필드로 가질 수 있다.
    • 이 때, 필드에 @Enumerated 어노테이션이 필요하다.
  • date 타입을 가질 수 있다.
    • 날짜 타입은 필드에 @Temporal을 사용하여 매핑.
  • description 필드는 String이며 Lob 타입이다.
    • @Lob 타입은 CLOB, BLOB 타입을 매핑할 수 있다.

필드와 컬럼 매핑

어노테이션설명

@Column 컬럼과 필드를 매핑
@Enumerated 자바의 enum 타입 매핑
@Temporal 날짜 타입 매핑
@Lob BLOB, CLOB 타입 매핑
@Transient 특정 필드를 데이터베이스에 매핑하지 않을떄 사용. 매핑 제외
@Access JPA가 엔티티에 접근하는 방식 지정

@Column

객체 필드를(멤버변수) 테이블 컬럼에 매핑할 때 사용

속성기능기본값

name 필드와 매핑할 테이블의 컬럼 이름 객체의 필드 이름. 카멜 캐이스
nullable null 값의 허용 여부 설정. false로 설정시 허용 안하므로 not null 제약 조건 추가 true
unique 한 컬럼에 유니크 제약 조건 걸 때 사용. 만약 두 컬럼 이상을 사용하여 유니크 제약조건을 걸 경우, 클래스 레벨(엔티티) 에서 @Table.uniqueConstraints 를 사용해야 한다  
length 문자 길이 제약 조건, String 타입에만 사용 255
precision, scale BigDecimal 타입에서 사용. precision : 소수점 포함 전체 자릿수, scale: 소수점 아래 자릿수.dobule, float 타입에는 적용되지 않고, 아주 큰 숫자나 정밀한 소수에만 사용  
columnDefinition DB에 컬럼 정보를 직접 줄 수 있음  
insertable 엔티티 저장시 이 필드도 같이 저장. false로 설정시 이 필드는 DB에 저장하지 않음 true
updatable 엔티티 수정시 이 필드도 같이 수정. false로 설정시 이 필드는 DB에 수정하지 않음. 읽기 전용일 때 사용 true
table 하나의 엔티티를 두 개 이상의 테이블에 매핑할 때 사용 현재 매핑된 테이블(엔티티클래스)

@Enumerated

객체 필드를(멤버변수) enum 타입 맵핑시 사용

속성기능기본값

value EnumType.ORDINAL: enum 순서를 DB에 저장, (숫자) EnumType.ORDINAL
  EnumType.String: enum 이름을 DB에 저장 EnumType.ORDINAL

@Temporal

날짜 타입 (Date, Calendar)를 매핑할 때 사용

속성기능기본값

value TemporalType.DATE : 날짜. DB date 타입과 매핑 필수로 지정해야함
  TemporalType.TIME : 시간. DB time 타입과 매핑  
  TemporalType.TIMESTAMP : 날짜와 시간. DB timestamp 타입과 매핑  

@Lob

DB의 BLOB, CLOB 타입과 매핑한다

@Lob은 지정할 수 있는 속성이 없다. 대신 매핑 필드 타입이 문자면 CLOB, 나머지는 BLOB으로 매핑한다

  • CLOB : String, char[], java.sql.CLOB
  • BLOB : byte[], java.sql.BLOB

@Transient

이 필드는 잘 매핑하지 않는다. DB에 값을 저장하지도, 조회하지도 않고 임시로 객체에 어떤 값을 보관하고 싶을 때 사용

  • 예를 들어 컬럼들을 이용한 응답값을 엔티티에 담고 있을때도 한 예가 된다.
@Transient
private String 임시메모;

@Access

JPA가 엔티티 클래스에 접근하는 방식을 지정

  • 필드 접근 : AccessType.FIELD로 지정. 필드에 직접 접근. private 이여도 접근할 수 있음!
  • 프로퍼티 접근 : AccessType.PROPERTY로 접근 . 접근자(getter)를 사용

4.4 데이터베이스 스키마 자동 생성

JPA는 데이터베이스 스키마를 자동하는 생성하는 기능을 지원한다 -> 테이블들도 자동으로 생성

  • 책에서는 xml 기반으로 설정하였지만, 스프링 부트 properties를 이용한 설정을 적겠다.
spring:
  datasource:
    url: jdbc:h2:tcp://localhost/~/h2/test  # h2 jdbc url
    driver-class-name: org.h2.Driver        # JDBC Driver
    username: sa                            # userID
    password:                               # password
​
  jpa:
    database: h2
    show-sql: true
​
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect #Dialect, ?? ??
        show_sql: true
        format_sql: true
        use_sql_comments: true
        id:
          new_generator_mappings: true
    hibernate:
      ddl-auto: validate none create update create-drop
​
  • spring.jpa.hibernate.show-sql : true로 지정하면 콘솔에 실행되는 sql을 출력한다.
  • spring.jpa.hibernate.ddl-auto : 속성 이름처럼, ddl을 자동으로 설정하거나 설정하지 않는 옵션들을 지정할 수 있다.
    • 애플리케이션 실행 시점에 테이블이 자동으로 생성되므로 테이블을 직접 생성하는 수고를 덜 수 있따.
    • 하지만 운영환경이나 개발서버에서는 사용하지 않는 것이 좋다.

ddl-auto의 옵션들

  • create : 기존 테이블을 삭제하고 새로 생성한다. DROP + CREATE -> 애플리케이션 실행시점에 실행
  • create-drop : create 속성에 추가로 애플리케이션을 종료할 때 생성한 DDL을 제거. DROP + CREATE + DROP
  • update : 테이블과 엔티티 매핑정보를 비교하여, 변경 사항만 수정한다
    • 참고 : 기존에 있던 컬럼을 없애지는 않는다.
  • validate : 테이블과 엔티티 매핑정보를 비교해서 차이가 있으면 경고를 남기고 애플리케이션을 실행하지 않는다.
    • DDL을 수정하진 않는다. 검증하고 다르다면 실행X
  • none : 자동 생성 기능을 사용하지 않는다.
    • 자동 생성 기능을 사용하지 않을것이라면 속성 자체를 적지 않거나(생략) none이나 유효하지 않은 옵션값을 주면 된다.
    • none은 유효하지 않는 옵션 값에 포함된다.

책에서의 개발 환경에 따른 ddl-auto의 추천 전략이다.

  • 개발 초기단계 create or update
  • 자동화된 테스트 단계와 CI 서버는 create or create-drop
  • 테스트 서버는 update 또는 validate
  • 스테이징과 운영 서버는 validate 또는 none

이름 매핑전략

단어와 단어사이에 자바 언어는 관례상 Camel Case를 사용하고, DB는 언더스코어(_)를 주로 사용한다.

네이밍 컨벤션에는 여러가지가 있다.

  • camelCase: 앞자는 소문자 단어 사이에 대문자
  • PascalCase: camleCase와 같은데 첫 글자가 대문자이다. Initial Capitals, Initial Caps, InitCaps 로도 불린다.
  • snake_case: 모든 문자는 소문자(lowercase)로 단어간 구분은 언더스코어(_)로 구분한다.
  • kebab-case: 모든 문자는 소문자(lowercase)로 단어간 구분은 대시(-)로 구분한다.
  • ALL CAPS: all capitals 의 줄임말로 모든 글자를 대문자로 쓴다.

@Column을 사용하여 필드의 이름을 지정할 때, 속성을 명시적으로 사용해서 _를 붙여줘야 하는 귀찮음이 있다.

하지만 책에선 hibernate.jeb.naming_strategy 이지만,

  • 공식 doc 문서에 따르면 org.hibernate.cfg.NamingStrategy는 더 이상 사용하지 않는다

spring boot에서는 spring.jpa.hibernate. 의 implicitStrategy 또는 physicalStrategy 를 이용한다.

스프링 부트에서는 기본적으로 물리 네이밍 전략을 SpringPhysicalNamingStrategy 를 사용

모든 도트는 밑줄로 대체, Camel Case 대문자는 밑줄로 대체, 모든 테이블은 소문자로 구성

  • ImplicitNamingStrategy(암시적 명칭 전략)
  • PhysicalNamingStrategy(물리적 명칭 전략)

Implict Naming Strategy (암시적 명칭 전략)

  • 명시적으로 naming이 지정되지 않은 Entity들의 명칭을 만들어주는 방식.
  • 그렇기 @Table, @Column 등의 방법으로 명칭을 미리 지칭한 경우 해당 전략은 적용되지 않는다.

The ImplicitNamingStrategy would only be applied if an explicit name was not given. 출처 : Hibernate ORM 5.4.27.Final User Guide

  • 해당 방법은 기본적으로 ImplicitNamingStrategyJpaCompliantImpl 방식을 따르며, JPA에 정의한 변수, 클래스 명칭 그대로 적용된다.
  • 만약 사용자가 직접 전략을 구상하고 싶다면 ImplicitNamingStrategy 인터페이스나 해당 자식 클래스들을 상속받아 구현하고 적용하면 된다.
    • 구현한 클래스명을 properties에 설정.
    • spring.jpa.hibernate.implicitStrategy = 구현한 클래스명

예시) 참조

Physical Naming Strategy (물리적 명칭 전략)

전략 이름대로, 물리 데이터베이스 테이블명과 컬럼명을

DB의 기본 전략인 under_score로 사용하지 않고 지정된 형식대로 사용.

  • 만약 기존의 개발자가 Entity의 일부 필드는 @Column으로 명시했고 그 외의 경우는 따로 만든 CustomImplicitNamingStrategy를 적용했다고 가정.
  • 하지만 DB변경으로 명칭 정책이 바뀜에 따라 Column과 Table 명칭을 Uppercase, Snake 표기법으로 변경한다면 ?

개발자는 기존의 암시적 명칭 전략을 변경하는 작업과 동시에, 코드상에 명시적으로 정의한 명칭들을 전부 수정해야 한다.

물리적 명칭 전략은 위에 대해 훌륭한 대책이 된다.

  • 해당 전략은 명시적 또는 암시적으로 명칭이 결정되든 항상, 마지막으로 적용.
  • 명시적, 암시적 전략이 먼저 적용되고 그 이후에 적용이 된다.
  • 공식 문서에서는 DB의 공통적인 규칙(Upper or lowercase, Snake case, 명칭 약자 등)을 적용할 때 사용하도록 권장하고 있다.

기본값으로는 logical_name 즉, 명시적, 암시적 명칭을 그대로 사용

이를 변경하려면 PhysicalNamingStrategy 인터페이스나 해당 자식들을 상속받아 정의하면 된다.

물리적 명칭 전략에선 다음 3가지가 기본으로 주어진다

  • org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
    • Deprecated 됨. 사용 x
  • org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    • 변수 이름을 그대로 DB에서 사용 - @Table에서 지정한 설정대로 그대로 사용 가능.
  • org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
    • 변수 이름이 카멜케이스면 언더스코어로 바꿔주는 전략
  • DB의 공통적인 명칭규칙은 물리적 명칭 전략, 그 외의 경우는 명시적, 암시적 명칭 전략을 사용하는 것이 권장된다.

4.6 기본 키 매핑

@Entity
public class Member {
  
  @Id 
  @GeneratedValue(strategy = "전략") // 기본키 생성 전략 
  @Column(name="ID")
  private String id;
}
​
public @interface GeneratedValue {
    GenerationType strategy() default GenerationType.AUTO;s
    String generator() default "";
}
​
public enum GenerationType {
    TABLE,
    SEQUENCE,
    IDENTITY,
    AUTO;
​
    private GenerationType() {
    }
}

기본 키 지정

  • @Id 어노테이션으로 필드에 매핑.
  • 자바 기본형(primitve type) 또는 래퍼(Wrapper type)만 가능.
    • String
    • java.util.Date
    • java.util.LocaldateTime
    • javal.sql.Date
    • java.math.BigDecimal
    • java.math.BigInteger

기본 키 생성 전략

  • @GeneratedValu 어노테이션으로 ID 필드에 매핑
  • strategy = GenerationType 으로 전략을 지정.
    • 디폴트는 AUTO

JPA가 제공하는 기본 키 생성 전략 (Strategy)

  1. 직접 할당 : 기본 키를 애플리케이션에 직접 할당
  2. 자동 생성 : 대리 키 사용 방식.

자동 생성 전략 : IDENTITY (GenerationType(strategy=IDENTITY))

IDENTITY: 기본키 생성을 데이터베이스에 위임한다.

 

  1. GenerationType.IDENTITY
  2. MySQL, PostgreSQL, SQL Server, DB2, MariaDB에서 사용.
  3. AUTO_INCREMENT 기능 제공
  4. 저장(persist, save) 하고 나서야 기본 키 값을 얻을 수 있다.
  5. 엔티티를 실제 DB에 저장해야 ID값을 얻을 수 있으므로 save 즉시 INSERT SQL이 발동하며 트랜잭션을 지원하는 쓰기 지연이 동작하지 않는다
    • 데이터베이스에 저장한 후에 식별자를 조회해서 엔티티의 식별자에 값을 할당하는것

자동 생성 전략 : SEQUENCE (GenerationType(strategy=SEQUENCE))

데이터베이스 시퀀스를 사용해서 기본키 할당

  • 오라클, PostgreSQL, DB2, H2 에서 주로 사용
  • GenerationType.SEQUENCE
  • @GeneratedValue(generator="시퀀스 생성기 등록")
  • @Entity
    @SequenceGenerator (
    	name="BOARD_SEQ_GENERATOR",
    	sequenceName="BOARD_SEQ", //매핑할데이터베이스시퀀스이름
    	initialValue=1, all○cati○nsize=1)
    public Class B○ard {
    	@Id
    	@GeneratedValue(Strateqv = Generati○nType.SEQUENCE/
    	generat○r="BOARDSEQGENERATOR")
    	private L○ng id;
      ...
    }
  • SEQUENCE 전략은 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회 한 후 엔티티에 식별자를 set 하고 엔티티를 영속성 컨텍스트에 저장. 이후 플러시가 일어나면 엔티티를 실제로 디비에 저장.

@SequenceGenerator의 옵션들

  • name : 식별자 생성기 이름. 값은 무조건 필수이다.
  • sequenceName : DB에 등록되어있는 시퀀스 이름.
    • 기본값 : hibernate_sequence
    • 간혹가다 MySQL 등을 사용하는데, hibernate_sequence 테이블이 있따면 어떤 엔티티에 전략을 잘못 설정한것
  • initiolValue : DDL 생성시에 사용. 시퀀스 DDL을 생성할 떄 처음 시작하는 수를 지정
    • 기본값: 1
  • allocationSize : 시퀀스 한 번 호출에 증가하는 수 (성능 최적화에 사용)
    • 기본값 : 50
  • catalog, schema : DB catalog, schema 이름

기본 키 자동 생성 전략이 다른 이유는 데이터베이스 벤더마다 지원하다 방식이 다르다

  • 오라클은 시퀀스 제공, MySQL는 시퀀스 제공 X -> AUTO_INCREMENT 사용
  • 따라서 SEQUENCE나 IDENTITY 전략은 DB에 의존한다

기본 키 직접 할당 전략은 개발자가 직접 setId로 값을 할당하는 방식.

TABLE 전략

TABLE 전략은 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 시퀀스를 흉내내는 전략

이 전략은 테이블을 사용하므로 모든 DB에 적용 가능.

이 전략은 데이터베이스와 한번 더 통신하는 단점이 있다.

최적화 하려면 @TableGenerator.allicationSize를 사용하면 되며, SEQUENCE 전략과 같다.

@GeneratedValue(strategy = GenerationType.TABLE, generator= "BOARDSEQ_GENERATOR")

create table MY_SEQUENCES {
	sequence_name varchar(255) not null,
	next_val bigint,
	primary key(sequence_name)
}
  • sequence_name을 시퀀스 이름으로 사용
  • next_val을 시퀀스 값으로 사용
```JAVA
@Entity
@TableGenerator (
    name="BOARD_SEQ_GENERATOR",
    table="MY_SEQUENCES",
    pkColumnValue="BOARD_SEQ", allocationSize=1
public class Board {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,
                    generator= "BOARDSEQ_GENERATOR")
    private Long id;
```
  • 테이블에 값이 없으면 JPA가 값을 INSERT 하면서 초기화 하므로 미리 초기화 할 필요는 없다 .

TableGenerator 속성

  • name : 식별자 생성기 이름
    • 기본 값 필수
  • table : 키생성 테이블명
    • 기본 값: hibernate_sequences
    • 변경이 가능하다.
  • pkColumnName : 시퀀스 컬럼명
    • 기본 값 : sequence_name
  • valueColumnName : 시퀀스 값 컬럼명
    • 기본 값 : next_val
  • pkColumnValue : 키로 사용할 값 이름
    • 기본 값 : 엔티티이름
  • initialValue : 초기 값, 마지막으로 생성된 값이 기준이다.
    • 기본 값 0
  • allocationSize : 시퀀스한번호출에증가하는수(성능최적화에 사용)
    • 기본 값 50
  • catalog, schema : 데이터베이스 catalog, schema
    • 기본 값 이름
  • uniqueconstraints(DDL) : 유니크 제약 조건을 지정할 수 있다

AUTO 전략

@GenerationValue(strategy = GenerationType.AUTO) 는 DB 방언(Dialect)에 따라

IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택한다.

예를들어 오라클을 사용하면 SEQUENCE를, MySQL을 사용하면 IDENTITY를 사용한다

기본키 매핑 정리

영속성 컨텍스트는 엔티티를 식별자 값 으로 구분하므로 영속 상태로 만들라면 반드시 식별자 값이 있어야 한다. em.persist() 메서드를 호출한 직후에 발생하는 일을 식별자 할당 전략별로 정리하면,

  • 직접 할당 : em.persist()를 호출하기 전에 애플리케이션에서 직접 식별자 값을 할당해야함. 없으면 예외 발생
  • Member member = new Member();
    member.setId(1L);
  • SEQUENCE : DB 시퀀스에서 시퀀스 값을 획득한 후 영속성 컨텍스트에 저장
  • TABLE : DB 시퀀스 생성용 테이블에서 식별자 값을 획득한 후 위와 동일
  • IDENTITY: DB에 엔티티를 저장해서 식별자 값을 획득한 후 위와 동일
    • IDENTITY 전략은 테이블에 데이터를 저장해야 식별자 값을 획들할 수 있다.

권장하는 식별자 선택 전략

기본키의 조건 3가지

  • NOT NULL, UNIQUE, 변하면 안된다.

테이블 기본 키 선택 전략

  • 자연 키
    • 주민번호, 이메일, 전화번호
  • 대리 키
    • 시퀀스, auto_increment, 키생성 테이블 사용

JPA는 모든 엔티티에 일관된 방식으로 대리 키 사용을 권장한다

  • 비즈니스 환경은 언젠간 변하므로. 유일한 값이라도 생각되었떤 것들이 변화될 수 있다.

 

'스터디 > JPA 프로그래밍 스터디' 카테고리의 다른 글

JPA 프로그래밍 스터디 7장 정리  (1) 2022.10.01
JPA 프로그래밍 스터디 6장 정리  (0) 2022.10.01
JPA 프로그래밍 스터디 5장 정리  (0) 2022.09.13
JPA 프로그래밍 스터디 3장 정리  (0) 2022.09.04
JPA 프로그래밍 스터디 1장,2장  (0) 2022.08.31
    '스터디/JPA 프로그래밍 스터디' 카테고리의 다른 글
    • JPA 프로그래밍 스터디 6장 정리
    • JPA 프로그래밍 스터디 5장 정리
    • JPA 프로그래밍 스터디 3장 정리
    • JPA 프로그래밍 스터디 1장,2장
    ysk(0soo)
    ysk(0soo)
    백엔드 개발을 좋아합니다. java kotlin spring, infra 에 관심이 많습니다. email : kim206gh@naver.com github : https://github.com/devysk

    티스토리툴바