김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계맵핑과 Primary Key

2025. 2. 5. 20:51·김영한의 ORM 표준 JPA 프로그래밍(기본편)

Question

  • 데이터베이스 스키마 자동 생성 기능은 어떻게 활용하는 것이 좋은가?
  • @Entity 어노테이션에 대해 설명하시오
  • @Temporal이 의미하는 것은 무엇이며 이 어노테이션이 없어도 되게 하는 자바 클래스는?
  • @Enumerated는 어떤 타입으로 쓰는게 좋은가?
  • @Transient는 무엇을 의미하는가?
  • @GeneratedValue Identity에 대해 설명하시오
  • @GeneratedValue Sequence에 대해 설명하시오
  • 식별자는 어떻게 정의하는게 좋은가?

 

데이터베이스 스키마 자동 생성 기능

  • 애플리케이션 실행 시점에 DDL 자동 실행
  • 테이블 중심 -> 객체 중심 가능
  • 방언을 통해 데이터베이스에 맞는 적절한 DDL 생성
  • 이 기능은 운영서버에는 위험해 사용하지 않고 테스트용 또는 로컬 환경에서 사용
  • hibernate.hbm2ddl.auto=create 이런식으로 정의해서 사용
    • create: 기존 테이블 삭제 후 다시 생성
    • create-drop: create와 같으나 종료 시점에 테이블 드랍
    • update: 변경분만 반영(운영 DB에는 사용하면 안됨)
    • validate: 엔티티와 테이블이 정상 매핑되었는지만 확인
    • none: 사용하지 않음
    • 개발 초기: create/update
    • 테스트 서버: update/validate
    • 스테이징 운영: validate/none

 

@Entity

  • @Entity가 붙은 클래스는 JPA가 관리하게 됨
  • 파라미터가 없는 public 또는 protected 생성자가 꼭 필요함
  • final, enum, interface, inner 클래스 사용 불가
  • 저장할 필드에 final 사용 불가
  • 기본값은 클래스 이름을 그대로 사용하지만 name 속성으로 정의 가능

 

어노테이션 맵핑

  • @Column: 컬럼 맵핑
  • @Temporal: 날짜 맵핑
    • TemporalType.DATE: 2013-10-11과 같은 형식
    • TemporalType.TIME: 11:11:11과 같은 형식
    • TemporalType.TIMESTAMP: 2013-10-11 11:11:11과 같은 형식
    • LocalDate, LocalDateTime을 사용하면 생략 가능
  • @Enumerated: enum 타입 맵핑
    • EnumType.ORDINAL: enum 순서를 숫자로 데이터베이스에 저장(기본값)
    • EnumType.STRING: enum 이름을 데이터베이스에 저장
    • ORDINAL은 ENUM의 순서를 바꾸면 숫자도 바뀌어 위험하기에 STRING을 사용해야함
  • @Lob: BLOB, CLOB 맵핑
    • 맵핑하는 필드 타입이 문자면 CLOB 맵핑, 나머지는 BLOB 맵핑
    • CLOB: String, char[], java.sql.CLOB
    • BLOB: byte[], java.sql.BLOB
  • @Transient: 맵핑하지 않기
    • 임시로 보관하는 용도로 사용

 

@ Column

속성 설명 기본값
name 매핑할 테이블의 열 이름을 지정합니다. 필드명과 동일
unique true로 설정하면 해당 열에 유니크 제약 조건이 설정됩니다. false
nullable true로 설정하면 해당 열에 NULL 값을 허용합니다. true
insertable true로 설정하면 삽입(insert) 시 해당 열 값을 포함시킵니다. true
updatable true로 설정하면 갱신(update) 시 해당 열 값을 포함시킵니다. true
columnDefinition 데이터베이스 특정 DDL을 직접 정의할 수 있습니다. 빈 문자열 (기본 데이터베이스 DDL)
table 매핑할 테이블의 이름을 명시합니다. (다른 테이블과의 중복 방지) 기본 테이블명
length 문자열 자료형(VARCHAR)의 경우 열 길이를 지정합니다. 255
precision BigDecimal 자료형의 경우 열의 정밀도를 지정합니다. (숫자 전체 자리수) 0 (해당 없음)
scale BigDecimal 자료형의 경우 소숫점 이하 자리수를 지정합니다. (정밀도와 함께 사용) 0 (해당 없음)
insertable 해당 필드를 데이터베이스 INSERT 구문에 포함시킬지 여부를 정의합니다. true
updatable 해당 필드를 데이터베이스 UPDATE 구문에 포함시킬지 여부를 정의합니다. true

 

기본 키 맵핑 방법

  • 직접 할당: @Id만 사용
  • 자동 할당: @GeneratedValue
    • IDENTITY: 데이터베이스에 위임하며 주로 MYSQL에서 주로 사용
    • SEQUENCE: 데이터베이스 시퀀스 오브젝트를 사용하며 Oracle, PostgreSQL에서 주로 사용
      • @SequenceGenerator를 사용해야함
    • TABLE: 키 생성용 테이블을 하나 만들어 DB 시퀀스를 흉내내는 전략
      • @TableGenerator 필요하며 모든 DB에 적용 가능한 장점이 있으나 성능 문제로 잘 사용하지 않음
    • AUTO: 방언에 따라 자동 지정, 기본값

 

@GeneratedValue - Identity

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
  • 기본키 생성을 DB에 위임
  • 주로 MySQL, PostgreSQL, SQL Server에서 사용(MySQL의 AUTO_INCREMENT)
  • JPA는 주로 트랜잭션 커밋 시점에 INSERT SQL을 실행
  • AUTO_INCREMENT는 DB에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있음
  • IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL을 실행하고 DB에서 식별자를 조회

 

@GeneratedValue - Sequence

@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;

 

속성 설명 기본값
name 시퀀스 생성기를 식별하기 위한 이름을 지정합니다. 필수값 (기본값 없음)
sequenceName 데이터베이스에 있는 실제 시퀀스 이름을 지정합니다. 기본값 없음
initialValue 시퀀스의 초기 값을 지정합니다. 첫 번째 값이 반환될 때 시작하는 값입니다. 1
allocationSize 시퀀스가 한 번에 증가할 수 있는 값의 수를 지정합니다. 최적화에 사용됩니다. 50
schema 시퀀스가 존재하는 스키마 이름을 지정합니다. 기본 스키마
catalog 시퀀스가 존재하는 카탈로그 이름을 지정합니다. 기본 카탈로그

 

  • 시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트
  • 오라클, PostgreSQL, H2 등에서 사용

 

권장하는 식별자 전략

  • 기본 키 제약 조건: Not Null, Unique, Not Change
  • 미래까지 이 조건을 만족시키는 자연키는 찾기 어려워 대체키를 사용하는게 좋음
  • 예를 들어, 주민등록번호도 유일하긴 하지만 나라에서 저장하지 말라고 하면 저장 못하는 등의 문제가 있음.
  • 권장은 Long + 대체키 + 키 생성전략

'김영한의 ORM 표준 JPA 프로그래밍(기본편)' 카테고리의 다른 글

김영한의 ORM 표준 JPA 프로그래밍(기본편) - 상속관계 맵핑과 - @MappedSuperclass  (1) 2025.02.06
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 다대일, 일대다, 일대일, 다대다  (1) 2025.02.05
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계 단방향 맵핑, 양방향 맵핑  (1) 2025.02.05
김영한의 ORM 표준 JPA 프로그래밍(기본편) - 영속성 컨텍스트와 플러시  (2) 2025.02.05
김영한의 ORM 표준 JPA 프로그래밍(기본편) - JPA, Hibernate, JPQL  (4) 2025.02.04
'김영한의 ORM 표준 JPA 프로그래밍(기본편)' 카테고리의 다른 글
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 다대일, 일대다, 일대일, 다대다
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계 단방향 맵핑, 양방향 맵핑
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - 영속성 컨텍스트와 플러시
  • 김영한의 ORM 표준 JPA 프로그래밍(기본편) - JPA, Hibernate, JPQL
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      조회 성능 최적화
      프록시
      jpq
      log trace
      빈 후처리기
      김영한
      jdk 동적 프록시
      gesingleresult
      단방향 맵핑
      cglib
      @args
      JPQL
      requset scope
      락
      @discriminatorcolumn
      양방향 맵핑
      Thread
      스레드
      자바
      고급
      Target
      typequery
      페치 조인
      @discriminatorvalue
      버퍼
      프록시 팩토리
      hibernate5module
      WAS
      @within
      reentarantlock
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    김영한의 ORM 표준 JPA 프로그래밍(기본편) - 연관관계맵핑과 Primary Key
    상단으로

    티스토리툴바