JPA (4) 엔티티 매핑

김영한님의 자바 ORM 표준 JPA 프로그래밍 강의 정리

객체와 테이블 매핑

@Entity

  • @Entity가 붙은 클래스는 JPA가 관리하며 entity라 함
  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수
  • 기본 생성자 필수
  • final 클래스, enum, interface, inner class 사용할 수 없음
  • 저장할 필드에 final 사용할 수 없음
속성 설명 기본값
name JPA에서 사용할 엔티티 이름 지정
같은 클래스 이름이 없으면 가급적 기본값 사용
클래스 이름

@Table

  • @Table은 엔티티와 매핑할 테이블 지정
속성 설명 기본값
name 매핑할 테이블 이름 엔티티 이름을 기본값으로 사용
catalog DB catalog 매핑  
schema DB schema 매핑  
uniqueConstraints DDL 생성시에 unique 제약 조건 생성  

DB schema 자동 생성

  • DDL을 애플리케이션 실행 시점에 자동 생성
  • 테이블 중심 → 객체 중심
  • DB 방언을 활용해서 적절한 DDL 생성
  • 이렇게 생성된 DDL은 개발 환경에서만 사용해야 함
  • 생성된 DDL은 운영 서버에서 사용하지 않거나 수정 후 사용
  • hibernate.hbm2ddl.auto 속성
  • DB 방언마다 DDL이 달라짐
  • 운영 환경에서는 create, create-drop, update 사용 X
  • 개발 초기 단계: create 또는 update
  • 테스트 서버: update 또는 validate
  • 스테이징, 운영 서버: validate 또는 none
옵션 설명
create 기존테이블 삭제 후 다시 생성 (DROP + CREATE)
create-drop create와 같지만 종료 시점에 테이블 DROP
update 변경 부분만 반영 (운영DB에는 사용하면 안됨)
validate 엔티티와 테이블이 정상 매핑되었는지만 확인
none 사용하지 않음

DDL 생성 기능

  • 제약조건 추가
    // 필수 값 & 10자 초과 X
    @Column(nullable = false, length = 10)
    
  • 유니크 제약 조건 추가
@Table(uniqueConstraints = {@UniqueConstraint(name = "NAME_AGE_UNIQUE",
                                             columnName = {"NAME", "AGE"})})

@Column(unique = true)
  • DDL 생성 기능은 JPA 실행 로직에는 영향 X

필드와 컬럼 매핑

  • @Column: 컬럼 매핑
  • @Temporal: 날짜 타입 매핑
  • @Enumerated: enum 타입 매핑
  • @Lob: BLOB, CLOB 매핑
  • @Transient: 특정 필드를 컬럼에 매핑하지 않음 (매핑 무시)

@Column

속성 설명 기본값
name 필드와 매핑할 테이블의 컬럼 이름 객체의 필드 이름
insertable, updatable 등록, 변경 가능 여부 True
nullabe(DDL) null 값의 허용 여부 설정
false로 설정하면 DDL 생성시에 not null 제약 조건이 붙음
 
unique(DDL) @Table의 uniqueConstraints와 같지만 한 컬럼에 간단히 unique 제약 조건을 걸 때 사용  
columnDefinition(DDL) DB 컬럼 정보를 직접 줄 수 있음
예) varchar(100) default ‘EMPTY’
필드의 자바 타입과 방언 정보 사용
length(DDL) 문자 길이 제약 조건, String 에만 사용 255
precision, scale(DDL) BigDecimal 타입에서 사용 (BigInteger도 가능)
precision은 소수점을 포함한 전체 자릿수
scale은 소수의 자릿수
double, float에는 적용되지 않고 아주 큰 숫자나 정밀한 소수를 다룰 때만 사용
precision=19
scale=2

@Enumerated

  • Java enum 타입 매핑할 때 사용
  • ORDINAL 을 사용하지 않도록 주의(새로운 데이터를 추가할 때 순서에 의한 문제가 발생할 수 있음)
속성 설명 기본값
value EnumType.ORDINAL: enum 순서를 DB에 저장
EnumType.STRING: enum 이름을 DB에 저장
EnumType.ORDINAL

@Temporal

  • 날짜 타입(java.util.Date, java.util.Calendar) 매핑할 때 사용
  • LocalDate, LocalDateTime 사용할 때는 생략 가능
속성 설명 기본값
value TemporalType.DATE: 날짜, DB date 타입과 매핑
TemporalType.TIME: 시간, DB time 타입과 매핑
TemporalType.TIMESTAMP: 날짜와 시간, DB timestamp 타입과 매핑
 

@Lob

  • DB의 BLOB, CLOB 타입과 매핑
  • 지정할 수 있는 속성 X
  • CLOB: String, char[], java.sql.CLOB
  • BLOB: byte[], java.sql.BLOB

@Transient

  • 필드 매핑 X
  • DB에 저장하거나 조회하지 않음
  • 주로 메모리상에서 어떤 값을 보관하고 싶을 때 사용

기본 키 매핑

  • 직접 할당: @Id 만 사용
  • 자동 생성: @GeneratedValue
속성 설명
GeneratedType.IDENTITY DB에 위임 (MySQL)
GeneratedType.SEQUENCE DB 시퀀스 오브젝트 사용 (Oracle)
@SequenceGenerator 필요
GeneratedType.TABLE key 생성용 테이블 사용
모든 DB에서 사용
@TableGenerator 필요
GeneratedType.AUTO 방언에 따라 자동 지정
기본값

IDENTITY

  • 기본키 생성을 DB에 위임
  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용
  • JPA는 보통 트랜잭션 커밋 시점에 INSERT 쿼리 실행
  • AUTO_INCREMENT는 DB에 INSERT 쿼리를 실행한 이후에 ID 확인 가능
  • IDENTITY 전략은 em.peresist() 시점에 즉시 INSERT 쿼리를 실행 후, DB에서 식별자 조회

SEQUENCE

  • 시퀀스는 유일한 값을 순서대로 생성하는 특별한 DB 오브젝트
  • Oracle, PostgreSQL, DB2, H2에서 사용
  • @SequenceGenerator
속성 설명 기본값
name 식별자 생성기 이름 필수
sequenceName DB에 등록되어 있는 시퀀스 이름 hibernate_sequence
initialValue DDL 생성 시에만 사용
시퀀스 DDL을 생성할 때는 처음 1 시작하는 수를 지정
 
allocationSize 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용)
DB 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 함
50
catalog, schema DB의 catalog, schema 이름  
@Entity
@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR", sequenceName = "MEMBER_SEQ",
                   initialValue = 1, allocationSize = 1)
public class Member {

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

TABLE

  • 키 생성 전용 테이블을 만들어 DB 시퀀스를 흉내내는 전략
  • 모든 DB에 적용 가능하지만 성능 이슈가 있을 수 있음
  • @TableGenerator
속성 설명 기본값
name 식별자 생성기 이름 필수
table 키 생성 테이블 이름 hibernate_sequences
pkColumnName 시퀀스 컬럼 이름 sequence_name
valueColumnName 시퀀스 값 컬럼 이름 next_val
pkColumnValue 키로 사용할 값 이름 entity 이름
initialValue 초기값
마지막으로 생성된 값이 기준
0
allocationSize 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용) 50
catalog, schema DB의 catalog, schema 이름  
uniqueConstraints(DDL) unique 제약 조건 지정 가능  
@Entity
@TableGenerator(
	name = "MEMBER_SEQ_GENERATOR",
	table = "MY_SEQUENCES", pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
public class Member {

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

권장하는 식별자 전략

  • 기본 키 제약 조건
    • null이 아님
    • 유일한 값
    • 변하면 안됨
  • 3가지 조건을 다 만족하는 자연키를 찾기 어려움
  • 대리키(대체키)를 사용하는 것 권장
  • Long + 대체키 + 키 생성전략 사용