ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 엔티티 매핑
    Back-end/JPA 2022. 4. 11. 22:39

    JPA에서 가장 중요한 2가지는 '객체와 관계형 데이터베이스 매핑' & '영속성 컨텍스트' 이다.

     

    # 객체와 테이블 매핑

    @Entity

    • @Entity가 붙은 클래스는 JPA가 관리하는 엔티티라고 한다.
    • JPA를 사용해 테이블과 매핑할 클래스에는 반드시 @Entity를 지정해줘야 한다.
    • @Entity가 붙은 클래스는 기본 생성자가 필수이다. (public or protected 생성자)
    • final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
    • 클래스의 필드에 final을 사용할 수 없다.

     

    Q. @Entity가 붙은 클래스에 기본 생성자가 필수인 이유는?

    JPA 인터페이스의 구현체로 대부분 사용되는 Hibernate는 내부적으로 Class.newInstance()라는 Java Reflection을 사용해 해당 Entity의 기본 생성자를 호출해서 객체를 생성한다. 이때, Java Reflection은 생성자의 매개변수를 읽을 수 없기 때문에 반드시 기본 생성자를 정의해줘야 한다. 

     

    *Java Reflection

    구체적인 클래스 타입을 알지 못해도, 해당 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API

     

    참고) https://1-7171771.tistory.com/123

     

    Q. @Entity가 붙은 클래스의 필드에 final을 사용할 수 없는 이유는?

    JPA가 제공하는 fetchType 중 LAZY 로딩 방식을 사용하기 위해서 프록시 객체를 생성한다. 프록시 객체는 간단히 말해 '엔티티를 상속해 확장한 클래스'이다. final class는 상속이 불가능 하므로, JPA는 final class를 확장한 프록시 객체를 생성할 수 없게 되므로, final 클래스에는 @Entity를 사용할 수 없다.

    JPA가 프록시 객체를 생성할 때 Java Reflection API를 사용하는데, 이렇게 생성된 프록시 객체들의 필드를 초기화 하기 위해 setter를 사용한다. final 필드는 setter로 초기화할 수 없으므로 @Entity가 붙은 클래스의 필드에 final을 사용할 수 없다.

     

    참고) https://jithub.tistory.com/410

     

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

    • DDL(테이블과 같은 데이터 구조를 정의하는데 사용되는 명령어들)을 어플리케이션 실행 시점에 자동으로 생성해준다. 
    • 설정한 데이터베이스에 맞는 DDL을 생성해준다.

    속성 (hibernate.hbm2ddl.auto)

    • create : 기존 테이블 삭제 후 다시 생성 (DROP + CREATE)
    • create-drop : create과 같으나 종료시점에 테이블 DROP
    • update : 변경 내용만 반영
    • validate : 엔티티와 테이블이 정상 매핑되었는지만 확인
    • none : 사용하지 않음

    주의

    • 운영에는 절대 create, create-drop, update는 사용하면 안된다!
    • 개발 초기 : create or update
    • 테스트 서버 : update or validate
    • 스테이징(운영 환경과 동일한 테스트와 운영 사이 단계) & 운영 서버 : validate or none

     

    # 필드와 컬럼 매핑

    매핑 어노테이션 (hibernate.hbm2ddl.auto)

    • @Column : 컬럼 매핑
    • @Temporal : 날짜 타입 매핑
      • 최신 하이버네이트에서 지원하는 LocalDate, LocalDateTime을 사용할 때는 생략 가능

     

    • @Enumerated : enum 타입 매핑
      • EnumType.ORDINAL(enum 순서 저장), EnumType.STRING(enum 이름 저장) 2가지 타입이 존재한다.

     

    • @Lob : 데이터베이스 BLOB, CLOB 타입과 매핑
    • @Transient : 특정 필드를 컬럼에 매핑하지 않음(매핑 무시)
      • 데이터베이스 저장 X, 조회 X
      • 주로 메모리상에서만 임시로 어떤 값을 보관하고 싶을 때 사용한다.

     

    # 기본 키 매핑

    방법

    • 기본 키 직접 할당 --> @Id만 사용
    • 기본 키 자동 생성 --> @GeneratedValue와 함께 사용
      • IDENTITY
        • 기본 키 생성을 데이터베이스에 위임
        • 주로 MYSQL(AUTO_INCREMENT), PostgreSQL, SQL Server, DB2에서 사용
        • JPA는 보통 transaction commit 시점에 INSERT SQL을 실행한다. AUTO_INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에야 기본 키 값을 알 수 있다. 따라서, IDENTITY 전략을 사용한다면, EntityManager의 persist() 시점에 즉시 INSERT SQL을 실행하고, DB에서 식별자를 조회하도록 구성되어 있다.
      • SEQUENCE : 데이터베이스 시퀀스 오프젝트 사용, 주로 Oracle
        • @SequenceGenerator 필요
      • TABLE : 키 생성용 테이블 사용, 모든 데이터베이스에서 사용 가능
        • @TableGenerator 사용
      • AUTO : 연결된 데이터베이스에 따라 자동으로 지정 (기본값)

     

    🎈참고

    자바 ORM 표준 JPA 프로그래밍 - 기본편

    'Back-end > JPA' 카테고리의 다른 글

    [JPA] 값 타입  (0) 2022.04.28
    [JPA] 프록시와 연관관계 관리  (0) 2022.04.28
    [JPA] 상속관계 매핑과 @MappedSuperclass  (0) 2022.04.27
    [JPA] 연관관계 매핑  (0) 2022.04.14
    [JPA] 등장 배경, 사용 이유, 간단 구동 방식  (0) 2022.03.31

    댓글

Designed by Tistory.