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
기본 리스너 사용
여러 리스너를 등록했을 때, 이벤트 호출 순서
기본 리스너
부모 클래스 리스너
리스너
엔티티
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