본문 바로가기

Spring/JPA

자바 ORM 표준 JPA 프로그래밍 #3(엔티티)

들어가며

Entity와 Table을 정확히 매핑하는 일은 중요하다. JPA에서는 다양한 어노테이션을 통해 매핑을 지원한다. 각 어노테이션에 대해서 공부해 보자

 

대표적인 어노테이션

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

기본키 매핑: @Id

필드와 컬럼 매핑: @Column

연관관계 매핑: @ManyToOne, @JoinColumn

 

@Entity

  • JPA를 사용해서 테이블과 매핑할 클래스는 해당 어노테이션이 필수이다.
  • 기본 생성자가 필수적으로 있어야 한다.
  • final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
  • 저장할 필드에 final을 사용하면 안된다.

@Table

  • 생략이 가능하며 생략시 엔티티 이름을 테이블 이름으로 사용한다.
  • uniqueConstraints를 만들 수 있다.
  • catalog 기능이 있는 데이터베이스에서 catalog를 매핑한다.
  • schema 기능이 있는 데이터 베이스에서 schema를 매핑한다.

@Column

  • JPA의 실행 로직에는 영향을 주지 않는다.
  • nullable을 통해 null값 제약조건을 걸 수 있다.
  • length를 통해 길이 제약조건을 걸 수 있다.
  • name을 통해 컬럼이름과 매핑한다 없을시 필드 명과 같은 이름으로 매핑

@Id

  • 개발자가 엔티티에 직접 값을 할당 할 수 있다.
  • 그렇지 않으면 @GeneratedValue를 통해 기본키 식별자 생성 전략을 선택해야 한다.
  • GenerationType.IDENTITY
    - 기본키 생성을 데이터베이스에 위임하는 전략
    - MySQL, PostgreSQL, SQL Server, DB2에서 주로 사용함.
    - 기본키 생성 전략을 데이터베이스에 위임하기 때문에 이 전략을 사용한 테이블은 쓰기 지연이 동작하지 않는다.
    - 영속 상태가 되려면 식별자가 반드시 필요하기 때문에 persist()가 호출되는 순간 바로 INSERT SQL이 데이터베이스에 전달됨
  • GenerationType.SEQUENCE
    - 시퀀스를 지원하는 ORACLE, PostgreSQL, DB2, H2 데이터베이스에서 사용 가능
    - 시퀀스란 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다.
    - @SequenceGnerator를 통해 식별자 생성기 이름을 정한 후 사용
    - persist()를 호출 할 때 시퀀스를 이용해 식별자를 조회 한 후 식별자를 영속성 컨텍스트에 저장하여 사용 따라서 쓰기지연이 가능
    - @SequenceGenerator에는 allcationSize라는 속성이 있다 JPA는 데이터베이스에서 시퀀스를 조회한 후 조회한 시퀀스를 기본 키 값으로 이용한다. 따라서 총 2번 데이터베이스에 접근을 한다. 이러한 과정으로 인해 성능이 떨어지는것을 막기 위해 @SequenceGenerator의 allocationSize라는 속성을 통해 설정한 만큼의 size를 메모리에 시퀀스를 할당 해 할당된 값을 바탕으로 시퀀스를 생성한다. 
  • GenerationType.TABLE
    - 키 생성 전용 테이블을 안들어 여기에 이름과 값으로 사용할 컬름을 넣어 데이터베이스 시퀀스를 흉내내는 전략
  • GenerationType.AUTO
    - 데이터베이스 방언에 따라 IDENTITY, SEQUENCE 전략 중 하나를 자동으로 선택
    - ORACLE인 경우 SEQUENCE, MySQL인 경우 IDENTITY
    - TABLE이나 SEQUENCE전략이 선택될 경우 시퀀스나 키 생성용 테이블을 미리 만들어 두어야 함(스키마 자동 생성 기능을 사용할 경우 하이버네이트가 적절한 시퀀스나 키 생성용 테이블을 만들어 줌)

 

그 밖의 어노테이션

  • @Enumerated
    enum 타입을 매핑할 때 사용
  • @Temporal
    날짜 타입을 매핑할 때 사용
  • @Lob
    데이터베이스 BLOB, CLOB 타입과 매핑할 때 사용
  • @Transient
    해당 필드는 데이터베이스와 매핑하지 않는다.
  • @Access
    JPA가 엔티티 데이터에 접근하는 방식을 지정
    - 필드 접근: AccessType.FIELD로 지정, 필드에 직접 접근
    - 프로퍼티 접근: AccessType.PROPERTY로 지정, 접근자(Getter)를 사용해 접근