본문 바로가기
개인 공부/JPA (자바 ORM 표준 JPA 프로그래밍)

자바 ORM 표준 JPA 프로그래밍 : 엔티티 매핑 (4장)

by 희조당 2022. 10. 6.
728x90


🌀Entity

이 어노테이션을 붙이면 JPA가 해당 클래스를 테이블과 매핑시켜 관리한다.

JPA 관리하에 놓인 클래스를 엔티티라 부른다.

 

🧷 속성

  • name : 엔티티의 이름. 디폴트는 클래스 명, 다른 패키지의 엔티티 클래스와 겹치지 않아야 한다.

🧷 주의사항

  • 기본 생성자 : JPA는 엔티티 객체를 생성할 때 기본 생성자를 사용한다.
  • final 클래스, enum, interface, inner 클래스에 사용할 수 없다.
  • 저장할 필드에 final을 사용하면 안 된다.

🌀Table

엔티티와 매핑할 테이블을 지정한다. 

 

🧷 속성

  • name : 매핑할 테이블 이름. 디폴트는 엔티티 이름
  • catalog : 데이터베이스에서 catalog를 매핑
  • schema : 데이터베이스에서 schema를 매핑
  • uniqueConstraints : DDL 생성 시 유니크 조건을 건다. 

📌 다양한 매핑 사용

  • 🌀Enumerted : 자바 enum을 사용하기 위한 어노테이션
  • 🌀Temporal : 자바 날짜 타입을 사용하기 위한 어노테이션
  • 🌀Lob : 길이 제한이 없는 데이터베이스의 CLOB 타입을 이용하기 위한 어노테이션
package jpabook.start;

import javax.persistence.*;  //**
import java.util.Date;

@Entity
@Table(name="MEMBER")
public class Member {
    // ... 생략
    @Enumerated(EnumType.STRING)
    private RoleType roleType;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @Lob
    private String description;
    // Getter, Setter 생략..
}

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

JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 제공한다.

클래스의 매핑정보를 통해서 어떤 테이블의 어떤 칼럼을 사용하는지 알 수 있다.

JPA는 이 매핑정보와 데이터베이스 방언을 통해 스키마를 생성한다.

 

🧷 hibernate.hb2ddl.auto 속성 (스키마 생성 옵션)

  • create : 기존 테이블 삭제 후 생성
  • create-drop : create에서 종료 시점에 테이블을 DROP
  • update : 변경된 사항만 반영. 지원❌
  • validate : 엔티티와 테이블이 정상적으로 매핑되었는지 확인. 지원❌
  • none : 사용하지 않음. 사실 유효한 옵션이 아님

📌 DDL 생성 기능

위 예시에서 회원 이름이 필수로 입력되어야하고, 10자를 초과하면 안 된다는 조건이 생겼을 때,

자동으로 생성되는 DDL에 이 조건을 반영하면 다음과 같다.

@Column(name="name", nullable = false, length = 10)
private String username;

 

@Table 어노테이션을 이용해서 유니크 조건을 추가하면 다음과 같다.

@Entity(name="Member")
@Table(name="MEMBER", uniqueConstraints = { @UniqueConstraint(
   name = "NAME_AGE_UNIQUE",
   columnNames = {"NAME", "AGE"} )}}
public class Member {
   ...
}

이런 생성 기능들은 DDL에만 사용되고 실제 JPA 실행 로직에는 영향을 주지 않는다.

직접 DDL을 만든다면 필요 없겠지만 개발자가 보기 쉽다는 장점이 있다.


📌 기본 키 매핑

JPA가 제공하는 데이터베이스 기본 키(PK) 생성 전략은 다음과 같다.

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

데이터베이스마다 지원하는 방식이 다르기 때문에 자동 생성 전략이 다양하다.

자동 키 생성 전략을 사용하기 위해선 🌀GeneratedValue 어노테이션을 함께 사용한다.

 

1️⃣ 직접 할당

persist() 로 엔티티를 저장하기 전에 애플리케이션에서 직접 기본 키를 할당하는 방법이다.

@Id를 적용할 수 있는 자바 타입은 기본형, 래퍼형, String 등이 있다.

Board board = new Board();
board.setId("id1");
em.persist(board);

2️⃣ IDENTITY

기본 키 생성 전략을 사용하는 데이터베이스에게 위임하는 전략이다.

지원하는 DB는 MySQL, SQL Server 등이 있다.

 

@GenerateValue 어노테이션의 strategy 속성을 사용해서 설정한다.

@Entity
public class Board {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   priavte Long id;
   ...
}

 

데이터베이스에 값을 저장하고 나서야 기본 키 값을 구할 수 있을 때 사용한다.

아래 예제를 보면 persist() 이후 데이터베이스에 저장할 때 할당된 id를 JPA가 조회한 것이다.

private static void logic(EntityManager em) {
   Board board = new Board();
   em.persist(board);
   System.out.println("board.id = " + board.getId());
}

3️⃣ SEQUENCE

시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트이다.

지원하는 DB는 오라클, H2 등이 있다.

 

@SequenceGenerator 어노테이션으로 시퀀스를 매핑하고 사용한다.

@Entity
@SequenceGenerator {
   name = "BOARD_SEQ_GENERATOR",
   sequenceName = "BOARD_SEQ",
   initialValue = 1, allocationsSize = 1)
public class Board {
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BOARD_SEQ_GENERATOR")
   private Long id;
   ...
}

 

시퀀스 사용 코드는 IDENTITY 전략과 같지만 내부 동작 방식은 다르다.

먼저 데이터베이스 시퀀스로 id를 조회하고 엔티티에 할당한 뒤 영속성 컨텍스트에 저장한다.

이후 플러시되면 데이터베이스에 저장된다.

 

🧷 @SequenceGenerator의 속성

  • name : 식별자 생성기 이름
  • sequenceName : 데이터베이스에 등록되어 있는 시퀀스 이름
  • initialValue : 시퀸스 DDL 실행 시 시작하는 값, 디폴트 1
  • allocationSize : 호출마다 증가하는 값, 디폴트 50
  • catalog, schema : 데이터베이스 catalog, schema 이름

4️⃣ TABLE

키 생성 전용 테이블을 만들어서 시퀀스를 따라 하는 전략이다.

모든 데이터베이스를 지원한다.

 

시퀸스 전략을 따라 하다 보니 내부 동작 방식도 구현 방법도 같다.

@Entity
@TableGenerator (
   name = "BOARD_SEQ_GENERATOR",
   table = "MY_SEQUENCE",
   pkColumnValue = "BOARD_SEQ", allocationSize = 1)
public class Board {
   @Id
   @GeneratedValue(strategy = GenerationType.TABLE, generator = "BOARD_SEQ_GENERATOR")
   private Long id;
   ...
}

 

🧷 @TableGenerator의 속성

  • name : 식별자 생성기 이름
  • table : 키 생성 테이블 명
  • pkColumnName : 시퀸스 칼럼명
  • valueColumnName : 시퀀스 값 칼럼명
  • pkColumnValue : 키로 사용할 값 이름
  • initialValue : 초기 값, 마지막으로 생성된 값이 기준, 디폴트 0
  • allocationSize : 호출마다 증가하는 값, 디폴트 50
  • catalog, schema : 데이터베이스 catalog, schema 이름
  • uniqueConstraints : 유니크 조건 지정

❌ 내부 동작 헷갈림 멈춰 ❌

IDENTITY : 데이터베이스에 저장하면 PK 할당

SEQUENCE : 데이터베이스에서 시퀸스를 조회해 엔티티에 먼저 PK를 할당하고 커밋 시 데이터베이스에 저장

TABLE : SEQUENCE와 동일

5️⃣ AUTO

선택한 데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 중 하나를 자동으로 선택한다.

대표적으로 MySQL을 사용하면 IDENTITY 전략을 사용한다.

데이터베이스를 변경해도 코드를 수정할 필요가 없다는 장점이 있다.


📌 필드와 칼럼 매핑 : 레퍼런스

JPA 제공하는 필드와 칼럼 매핑용 어노테이션들 다음과 같다. 

자세한 속성은 필요할 때마다 찾아보자!

  • 🌀Column : 칼럼 매핑
  • 🌀Transient : 특정 필드를 매핑❌
  • 🌀Access : JPA가 엔티티에 접근하는 방식 지정

 

댓글