반응형
Notice
Recent Posts
Recent Comments
관리 메뉴

간단한 개발관련 내용

14장 컬렉션과 부가기능 본문

IT 책/JPA (ORM 표준 JPA 프로그래밍)

14장 컬렉션과 부가기능

vincenzo.dev.82 2024. 11. 19. 13:59
반응형
  • 컬렉션 : 다양한 컬렉션과 특징을 설명한다
  • 컨버터 : 엔터티의 데이터를 변환해서 데이터베이스에 저장한다
  • 리스너 : 엔터티에서 발생한 이벤트를 처리한다
  • 엔터티 그래프 : 엔터티를 조회할 때 연관된 엔터티들을 선택해서 함께 조회한다

14.1 컬렉션

  • OneToMany, ManyToMany를 사용해서 일대다나 다대다 엔터티 관계를 매핑할 때
  • ElementCollection을 사용해서 값 타입을 하나 이상 보관할 때

자바 컬렉션의 특징 (중복, 순서)

  • Collection
    • 자바가 제공하는 최상위 컬렉션이다. 하이버네이트는 중복을 허용하고 순서를 보장하지 않는다고 가정한다.
  • Set
    • 중복을 허용하지 않는 컬렉션이다. 순서를 보장하지 않는다.
  • List
    • 순서가 있는 컬렉션이다. 순서를 보장하고 중복을 허용한다.
  • Map
    • key, value 구조로 되어 있는 특수한 컬렉션이다.

<aside> 💡

Map은 복잡한 매핑에 비해 활용도가 떨어지고 다른 컬렉션을 사용해도 충분하므로 생략했다. 참고로 Map은 @MapKey* 어노테이션으로 매핑할 수 있다.

</aside>

14.1.1 JPA와 컬렉션

  • 하이버네이트는 엔터티를 영속 상태로 만들 때 컬렉션 필드를 하이버네이트에서 준비한 컬렉션으로 감싸서 사용한다.
  • 하이버네이트가 제공하는 PersistentBag 타입으로 변경

14.1.2 Collection, List

  • 중복을 허용하면서 PersistentBag을 래퍼 컬렉션으로 사용한다.
  • 중복을 허용하기 때문에 add 메서드는 true를 반환하고 같은 엔터티 비교는 equals를 사용
  • 중복 엔터티 비교 없이 단순히 저장만하면 되기 때문에 엔터티를 추가해도 지연 로딩된 컬렉션을 초기화 하지 않는다.

14.1.3 Set

  • 중복을 허용하지 않으므로 add 메서드로 추가할 때마다 equals 메서드로 같은 객체가 있는지 비교한다.
  • HashSet은 해시 알고리즘을 사용하므로 hashCode()도 함께 사용해서 비교한다
  • Set은 엔터티를 추가할 때 중복된 엔터티가 있는지 비교해야 한다. 따라서 엔터티를 추가할 때 지연 로딩된 컬렉션을 초기화해야한다.

14.1. 4 List + @OrderColumn

  • OrderColumn을 추가하면 순서가 있는 특수한 컬렉션으로 인식한다. 순서가 있다는 의미는 데이터베이스에 순서 값을 저장해서 조회할 때 사용한다는 의미다.
  • 하이버네이트는 내부 컬렉션인 PersistentList를 사용한다.
  • 순서가 있는 컬렉션은 데이터베이스에 순서 값도 함께 관리한다. 그러나 단점이 있기 때문에 직접 만들어서 사용하거나 @OrderBy를 사용하기를 권장한다.
  • @OrderColumn의 단점
    • List의 요소 하나 삭제 시 모든 포지션 변경이 발생하여 update 쿼리가 수행되는 오버헤드가 있다
    • 물리적으로 중간값을 삭제하면 null 처리되어 조회 시 NullPointerException이 발생한다

14.1.5 @OrderBy

  • 데이터베이스의 order by 절을 사용해서 컬렉션을 정렬한다

<aside> 💡

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

</aside>

 

14.2 @Converter

  • 엔터티의 데이터를 변환해서 DB에 저장할 수 있다
  • boolean type 이 DB에 저장될 때 1 또는 0으로 저장되는데 Y, N으로 저장하고 싶을 때 사용한다.
  • @Converter 어노테이션을 사용하고 AttributeConverter 인터페이스를 구현해야 한다
public interface AttributeConverter<X,Y> {
	public Y convertToDatabaseColumn(X attribute);
	public X convertToEntityAttribute(Y attribute);
}

14.2.1 글로벌 설정

  • @Converter(autoApply = true) 옵션을 사용해서 모든 Entity boolean 속성 처리에 적용한다

14.3 리스너

  • 엔터티의 생명주기에 따라 이벤트 처리 가능

14.3.1 이벤트 종류

  • PostLoad
  • PrePersiste
  • PreUpdate
  • PreRemove
  • PostPersist : flush() 하여 insert 된 후
  • PostUpdate : flush() 하여 update 된 후
  • PostRemove : flush() 하여 delete 된 후

14.3.2 이벤트 적용 위치

  • 엔터티에 직접적용
    • 이벤트별 어노테이션 사용
  • 별도의 리스너 등록
    • 엔터티에 @EntityListeners(x.class)
  • 기본 리스너 사용

 

14.4 엔터티 그래프

  • FetchType.EAGER
  • JPA 2.1에 추가된 엔터티 그래프 기능을 사용하면 엔터티를 조회하는 시점에 함께 조회할 연관된 엔터티를 선택할 수 있다.
  • 엔터티 그래프 기능은 엔터티 조회시점에 연관된 엔터티들을 함께 조회하는 기능이다.

14.4.1 Named 엔터티 그래프

  • @NamedEntityGraphs 사용

14.4.2 em.find()에서 엔터티 그래프 사용

  • em.getEntityGraph() 로 가져온 후 em.find() 의 인자로 전달

14.4.3 subgraph

  • 손자까지 가져와야 할 때, Order —> OderItems —> Item
  • @NamedEntityGraph 하위에 subgraphs 적용

14.4.4 JPQL에서 엔터티 그래프 사용

  • em.setHint()

14.4.5 동적 엔터티 그래프

  • em.createEntityGraph()

14.4.6 엔터티 그래프 정리

  • ROOT엣 시작
  • 이미 로딩된 엔터티
  • fetchgraph, loadgraph의 차이

14.5 정리

  • 컬렉션
  • 컨버터
  • 리스너
  • 엔터티그래프
반응형