Chapter 14: 컬렉션과 부가 기능

1. 컬렉션

  • JPA는 자바에서 기본으로 제공하는 Collection, List, Set, Map 컬렉션을 지원한다

  • 사용하는 경우

    • @OneToMany @ManyToMany 를 사용해서 1:N이나 N:M 엔티티 관계를 매핑할 때

    • @ElementCollection 을 사용해서 값 타입을 하나 이상 보관할 때

  • Map

    • Map은 복잡한 매핑에 비해 활용도가 떨어지고, 다른 컬렉션을 사용해도 충분함

    • Map은 @MapKey* 어노테이션으로 매핑할 수 있다

1-1. JPA와 컬렉션

  • 하이버네이트는 엔티티를 영속 상태로 만들 때 컬렉션 필드를 하이버네이트에서 준비한 컬렉션으로 감싸서 사용한다

    • 하이버네이트는 컬렉션을 효율적으로 관리하기 위해 엔티티를 영속 상태로 만들 때, 원본 컬렉션을 감싸고 있는 내장 컬렉션 을 생성해서 내장 컬렉션을 사용하도록 참조를 변경한다

    • 하이버네이트가 제공하는 내장 컬렉션은 원본 컬렉션을 감싸고 있어서 래퍼 컬렉션 으로도 부른다

    • 이러한 특징 때문에 컬렉션을 사용할 때 즉시 초기화해서 사용하는 것을 권장한다

1-2. Collection, List

  • Collection, List는 엔티티를 추가할 때 중복된 엔티티가 있는지 비교하지 않고 단순히 저장만 하면 된다

    • 따라서 엔티티를 추가해도 지연 로딩 된 컬렉션을 초기화 하지 않는다

1-3. Set

  • Set은 엔티티를 추가할 때 중복된 엔티티 가 있는지 비교 해야한다

  • 따라서 엔티티를 추가할 때 지연 로딩 된 컬렉션을 초기화 한다

1-4. List + @OrderColum

  • List 인터페이스에 @OrderColumn 을 추가하면 순서가 있는 특수한 컬렉션으로 인식한다

    • 순서가 있다는 의미는 DB에 순서 값을 저장해서 조회할 때 사용한다는 의미다

    • 순서가 있는 컬렉션은 DB에 순서 값도 함께 관리한다

  • @OrderColumn 의 단점

    • INSERT 시 순서 값 필드를 UPDATE 하는 SQL이 추가로 발생한다

    • List를 변경하면 연관된 많은 위치 값을 변경해야 한다

    • 중간에 순서 값 필드에 값이 없으면 조회한 List에는 null이 보관되므로, 조회 시 컬렉션을 순회할때 NullPointerException이 발생한다

1-5. @OrderBy

하이버네이트는 Set에 @OrderBy를 적용해서 조회하면, 순서를 유지하기 위해 HashSet 대신에 LinkedHashSet을 내부에서 사용한다

2. @Converter

  • 컨버터를 사용하면 엔티티의 데이터를 변환해서 DB에 저장할 수 있다

  • 글로벌 설정을 하면 @Converter를 지정하지 않아도 모든 타입에 대해 자동으로 컨버터가 적용된다

3. 리스너

→ entity 생명 주기…! prepost

JPA 리스너 기능을 사용하면 엔티티의 생명 주기에 따른 이벤트를 처리할 수 있다

이벤트 적용 위치

  • 엔티티에 직접 적용

  • 별도의 리스너 등록 → @EntityListeners

  • 기본 리스너 사용

여러 리스너를 등록했을 때, 이벤트 호출 순서

  1. 기본 리스너

  2. 부모 클래스 리스너

  3. 리스너

  4. 엔티티

4. 엔티티 그래프

엔티티 그래프 기능은 엔티티 조회 시점 에 연관된 엔티티들을 함께 조회하는 기능

  • @NamedEntityGraph 사용

  • JPQL에서 엔티티 그래프를 사용할 때는 em.find() 와 동일하게 힌트만 추가

    • ex) .setHint()

  • 동적으로 엔티티 그래프를 구성하려면 em.createEntityGraph() method 사용

엔티티 그래프 특징

  • ROOT에서 시작

    • 엔티티 그래프는 항상 조회하는 엔티티의 ROOT에서 시작해야 한다

  • 이미 로딩된 엔티티

    • 영속성 컨텍스트에 해당 엔티티가 이미 로딩되어 있으면 그래프가 적용되지 않는다

      • 아직 초기화되지 않은 프록시에는 엔티티 그래프가 적용된다

  • fetchgraph, loadgraph의 차이

    • fetchgraph

      • 엔티티 그래프에 선택한 속성만 함께 조회

    • loadgraph

      • 엔티티 그래프에 선택한 속성뿐만 아니라 글로벌 fetch 모드가 FetchType.EAGER 로 설정된 연관관계도 포함해서 함께 조회

5. 정리

  • JPA가 지원하는 컬렉션 종류와 특징

  • 컨버터를 사용하면 엔티티의 데이터를 변환 해서 DB에 저장할 수 있다

  • 리스너를 사용하면 엔티티에서 발생한 이벤트를 받아서 처리할 수 있다

  • FETCH JOIN은 객체지향 쿼리를 사용해야 하지만, 엔티티 그래프를 사용하면 객체 지향 쿼리를 사용하지 않아도 원하는 객체 그래프를 한 번에 조회할 수 있다

Last updated