JPA - 엔티티매핑

엔티티 매핑


JPA는 기본적으로 Entity를 사용하여 매핑을 한다.

class 생성후 꼭 @Entity 어노테이션을 적용해 주어야 데이터베이스와 매핑이 된다.

  • 객체와 테이블 매핑 : @Entity , @Table

  • 필드와 컬럼 매핑
    • 컬럼 매핑 : @Column

    • 날짜 타입 매핑 : @Temporal

    • enum 타입 매핑 : @Enumerated

    • BLOB, CLOB 매핑 : @Lob

    • 특정 필드를 DB랑 연관짓지 않음 : @Transient

  • 기본 키 매핑 : @Id

  • 연관관계 매핑 : @ManyToOne , @JoinColumn , @OneToMany , @OneToOne , @ManyToMany

@Entity


- @Entity가 붙어야만 JPA가 관리  
- 기본 생성자가 꼭 필요 ( JPA 내부적 로직 필요 )  
- final , enum , interface , inner 사용 X

Entity로 선언이 되면 JPA는 Entity에 맞는 적절한 스키마를 자동 생성해준다.

  • DDL을 애플리케이션 실행 시점에 자동 생성
  • 테이블 중심 -> 객체 중심
  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • 생성된 DDL은 운영서버에서는 사용하지 않거나, 적절히 다듬은 후 사용

개발하면서 엄청 편리한 기능이지만 실제로 운영서버에서는 사용하면 안된다.

  • 운영장비에는 절대 create , create-drop , update 사용하면 안된다. (데이터 초기화 위험)
  • 개발 초기단계는 create 또는 update (프로젝트 생성 및 설정)
  • 테스트 서버는 update 또는 validate (테스트 및 개발 단계)
  • 스테이징과 운영 서버는 validate 또는 none (배포)

@Enumerated


  • Enum 타입을 매핑할 떄 사용
    • EnumType.ORIDINAL / 인덱스 번호를 저장
    • EnumType.String / 텍스트를 저장
  • ORDINAL는 사용하지 않는것을 추천한다. Enum에 새로운 데이터 추가시 전에 생성된 데이터랑 충돌 발생 할 수 있다. (운영상에서 큰 문제)

기본키 매핑 (PK)


PK의 데이터 값 셋팅하는 방법으로는 직접 데이터를 주입하는 방법과 데이터베이스의 SEQUENCE , AutoIncrement 를 사용하는 방법이 있다.
외로 테이블을 이용하여 SEQUNCE와 비슷하게 이용하는 방법이 있는데 잘 사용하지 않는다.

@Id

기본적으로 PK 매핑시 사용하며, @Id만 입력시 사용자가 직접 값을 셋팅해주어야 한다.

@GeneratedValue

3가지의 방법을 지원하며 , strategy = GenerationType.~ 으로 사용하며 default는 sequence이다.

  • INDENTITY (MySQL : AutoIncrement)

  • SEQUENCE (ORACLE : Sequence)

  • TABLE (테이블을 생성하여 시퀀스를 흉내)

SEQUENCE 방법

Sequence 사용시 기본적으로 hibernate의 Sequence를 사용하게된다.
hibernate의 Sequence는 다 공유하기때문에 PK가 일정하지 않다.

만약 각각 다른 Sequence를 이용하고 싶다면 @SequenceGenerator 를 사용하여 시퀀시를 만들어 사용한다.

SEQUENCE를 사용하면 JPA 영속성컨텍스트의 메커니즘에 따라 예외적으로 처리가 필요하다.

  • 영속성 컨텍스트는 캐시에 저장될때 PK값이 있어야 한다. 하지만 SEQUENCE PK 값이 존제하지 않기에 persist(entity) 시점에서 SEQ.NEXTVAL()를 불러 PK값을 가져온다.

  • 만약 이러한 방법을 사용시 DB 접근을 계속하기에 메모리적으로 부담을 가질 수 있다.

  • 이러한 문제를 해결하는 획기적인 방법이 있다. allocationSize 이다

  • allocationSize

    • 시퀀스를 부를때 셋팅된 값만큼 미리 불러온다.

    • 20을 미리 불러왔으면 DB에서는 21로 셋팅이 되어있다.

    • 다음 또 호출 할 경우 1 , 2 , 3 ,,,, 순으로 올라가며 만약 가져온 값과 호출할때 값이 똑같아 진다면 다시 셋팅된 값 만큼 값을 불러온다.

    • 하지만 문제점으로는 어플리케이션 종류시에는 미리 가져온 SEQUENCE는 돌아가지않고 날라가게 된다.

INDENTITY 방법

MySQL의 AutoIncrement 방법으로 자동으로 1씩 증가하게 된다.

IDENTITY를 사용하면 SEQUENCE와 마찬가지로 JPA 영속성컨텍스트의 매커니즘에 따라 예외적으로 처리가된다.

  • SEQUENCE와 같이 영속 컨텍스트에는 PK값이 있어야 한다. 하지만 IDENTITY는 인설트를 해야 PK값을 알 수 있다.
  • 예외로 IDENTITY 전략을 사용하면 persist(entity)시 insert쿼리를 날린다.

Table 방법

말그대로 PK를 저장하는 테이블을 따로 생성하여 PK를 SEQUNECE와 같이 불러와 테이블 데이터를 업데이트하는 방식이다.

하지만 데이터베이스를 접근하여 메모리를 낭비할 수 있기 때문에 잘 사용하지 않는다.

정리


권장하는 식별자 전략

- 기본 키 제약 조건 : null 아님 , 유일 , 변하면 안된다.  
- 미래까지 이 조건을 만족하는 자연키는찾기 어렵다. 대리키(대체키)를 사용하자.  
- 예를 들어 주민등록번호도 기본 키로 적절하지 않다.  
- 권장 : Long형 + 대체키 + 키 생성전략 사용  

Entity 생성시 가급적 Setter는 만들지 않는 편이 좋다.

- 유지보수 측면에서 추적하기에 편리하다

- 생성자를 통한 데이터 주입을 이용하자

- 후의 편의 메서드를 이용하여 값을 셋팅

Entity 작성시 가급적이면 매핑과 규약을 적어주는 편이 좋다.

- 개발자가 Entity만 확인후 테이블의 구성을 이해할 수 있다.

Categories:

Updated:

Leave a comment