JPA 엔티티 매핑

Gunjoo Ahn·2023년 6월 28일
0
post-custom-banner

HBM2DDL 주의사항

운영 서버에는 당연하게도 DDL 수정을 시도하는 옵션을 절대 사용해서는 안된다. 개발 단계에 계속 사용하다 모르고 커밋할 경우가 있는데, CI/CD 파이프라인 단계에서도 해당 부분에서 실수가 생기지 않도록 구조적으로 방어하는 것이 필요하다고 생각한다.

운영 서버에 올리기 전에 혹시라도 DDL이 날라가는 옵션이 켜져있는지 꼭 확인하도록 하자!!

jpa.hibernate.ddl-auto , jpa.properties.hibernate.hbm2ddl.auto 차이가 뭔가요?

Hibernate’s own internal property name for this (if you happen to remember it better) is hibernate.hbm2ddl.auto.
You can set it, along with other Hibernate native properties, by using spring.jpa.properties.* (the prefix is stripped before adding them to the entity manager).

Spring Docs

@GenerateValue

strategy = GenerationType.IDENTITY

IDENTITY 전략은 데이터를 데이터베이스에 저장한 이후에 데이터베이스가 부여한 키 값을 조회할 수 있다. 따라서 엔티티에 식별자 값을 할당하려면 JPA는 추가로 데이터베이스를 조회하여야한다. JDBC3 스펙에 추가된 Statement.getGeneratedKeys()를 사용하면 데이터를 저장하면서 동시에 생성된 기본 키 값도 얻어올 수 있다. Hibernate는 이 메소드를 사용하여 데이터베이스와 한번만 통신한다.

추가로 주의할 점은 엔티티가 영속 상태가 되려면 식별자가 반드시 필요하다는 점이다. 그러므로 em.persist()를 호출함과 동시에 INSERT 쿼리가 날날려서 식별자를 데이터베이스로부터 받아온다. 즉 이 전략을 선택할 경우 트랜잭션의 쓰기 지연이 동작하지 않는다.

strategy = GenerationType.SEQUENCE

신입때 MySQL만 사용하다 처음 GenerationType.SEQUENCE를 접했을 때 당황했던 부분이 있다. 바로 데이터베이스에 있는 시퀀스 값이 확확 건너 뛴다는 점이었다. 값이 1씩 증가할줄 알았는데 아니었던 것이다.

SEQUENCE 전략은 데이터베이스 시퀀스를 통해 식별자를 조회하는 추가 작업이 필요한 전략이다. 이때 시퀀스를 조회하는 회수를 줄이기 위하여 한번에 시퀀스 값을 증가시키고 메모리에서 증가분만큼 식별자를 얻어와 할당하는 것이다. 그래서 신입때 봤던 데이터베이스 시퀀스 값이 1씩 증가하지 않고 기본으로 설정된 50씩 증가했던 것이다.

이 부분은 GenerationType.TABLE도 마찬가지이다.

@Temporal

@Temporal을 사용하지 않고 있다. 그래서 JPA 스펙인지, hibernate 기능인지, 언제부터 사용하지 않아도 되었는지 이번 기회에 확인하고 싶었다.

  1. JPA 스펙으로는 남아있으며, hibernate를 사용하지 않고 다른 ORM을 사용할 경우 @Temporal을 명시적으로 사용해주어야한다. @Temporal
  2. Hibernate 5 이상부터는 @Temporal을 생략해도 된다.

JPA Auditing

시간 관련 컬럼하면 떠오르는 created at ,updated at, deleted at 등등이 있다. JPA Auditing을 통하여 쉽게 일괄 적용할 수 있다.

https://docs.spring.io/spring-data/jpa/docs/1.7.0.DATAJPA-580-SNAPSHOT/reference/html/auditing.html

권장하는 식별자 선택 전략

데이터베이스 기본 키는 다음 세 가지 조건을 모두 만족해야 한다.

  1. null 값을 허용하지 않는다
  2. 유일해야 한다.
  3. 변해서는 안 된다.

테이블의 기본 키를 선택하는 전략은 크게 2가지가 있다.

  • 자연 키(natural key)
    • 비즈니스에 의미가 있는 키
    • ex) 주민등록번호, 이메일, 전화번호
  • 대리 키(surrogate key)
    • 비즈니스와 관련 없는 임의로 만들어진 키, 대체 키로도 불린다
    • ex) 오라클 시퀀스, auto_increment, 키 생성 테이블 사용

자연 키보다는 대리 키를 권장한다

비즈니스 환경은 언젠가 변한다. 주민등록번호와 같이 그럴듯해보이는 값 조차 정부 정책의 변경으로 인하여 저장할 수 없는 값이 되어 기본 키로 사용할 수 없게 되기도 한다.

기본 키의 조건을 현재는 물론이고 미래까지 충족하는 자연 키를 찾기란 쉽지 않다. 대리 키는 비즈니스와 무관한 임의의 값이므로 요구사항이 변경되어도 기본 키가 변경되는 일은 드물다.

대리 키를 기본 키로 사용하되 주민등록번호나 이메일처럼 자연 키의 후보가 되는 컬럼들은 필요에 따라 유니크 인덱스를 설정해서 사용하는 것을 권장한다.

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

비즈니스 요구사항은 계속해서 변하는데 테이블은 한 번 정의하면 변경하기 어렵다. 그런 면에서 외부 풍파에 쉽게 흔들리지 않는 대리 키가 일반적으로 좋은 선택이라 판단할 수 있다.

데이터 중심 객체 설계의 문제점

데이터 중심으로 객체를 설계할 경우 객체와 연관된 객체를 참조를 통하여 연결할 수 없게 된다. 객체가 테이블과 동일하게 외래 키만 들고 있다면, 연관 객체를 찾기 위하여 해당 외래 키를 가지고 다시 조회하는 등의 추가적인 프로세스가 소요된다. 이 부분을 해결하는 것이 JPA(ORM)이다.

객체는 참조를 사용하여 연관 객체를 찾고 테이블은 외래 키로 찾는다. JPA는 객체의 참조와 테이블의 외래 키를 매핑해서 객체에서는 참조를 사용하고 테이블에서는 외래 키를 사용할 수 있도록 한다.

Reference

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

profile
Backend Developer
post-custom-banner

0개의 댓글