본문 바로가기
  • 실행력이 모든걸 결정한다
Spring 사전 준비/JPA Hibernate

[JPA] JPA와 컬렉션

by 김코더 김주역 2022. 8. 24.
반응형

1. 래퍼 컬렉션

- 원본 컬렉션을 감싸고 있는 내장 컬렉션을 래퍼 컬렉션이라고 부른다.

- Hibernate에서 엔티티를 영속 상태로 만들면 그 안에 있는 컬렉션 타입은 래퍼 컬렉션 타입으로 변경된다.

※ org.hibernate.collection.internal.*

 

 

 

2. Collection, List 타입

- 엔티티가 영속 상태가 되면 org.hibernate.collection.internal.PersistenceBag 타입으로 변환된다.

- 중복을 허용하고 순서를 보장하지 않는다.

- 아래와 같이 ArrayList 타입으로 초기화해서 사용하면 된다.

@OneToMany
@JoinColumn
private Collection<Member> members = new ArrayList<Member>();

※ 위와 같은 일대다 단방향 매핑은 외래키가 반대편 테이블에 생성되어 관리된다.

- 중복된 엔티티를 비교하지 않기 때문에 엔티티를 추가해도 지연 로딩된 컬렉션을 초기화하지 않는다.

 

 

 

3. Set 타입

- 엔티티가 영속 상태가 되면 org.hibernate.collection.internal.PersistentSet 타입으로 변환된다.

- 중복을 허용하지 않고 순서를 보장하지 않는다.

- 중복을 비교할 때 hash 알고리즘을 사용하며, hashcode()와 equals()를 내부적으로 이용해서 비교한다.

- 아래와 같이 HashSet 타입으로 초기화해서 사용하면 된다.

@OneToMany
@JoinColumn
private Set<Member> members = new HashSet<Member>();

- 중복된 엔티티를 비교해야 하기 때문에 엔티티를 추가할 때 지연 로딩된 컬렉션을 초기화한다.

 

 

 

4. List 타입 + @OrderColumn

- List 타입에 @OrderColulmn 어노테이션을 추가하면 순서가 있는 특수한 컬렉션으로 인식한다. DB에 순서 값을 저장해서 조회할 때 사용되며, 순서 값은 다(N) 쪽 테이블에 저장된다.

- 엔티티가 영속 상태가 되면 org.hibernate.collection.internal.PersistenceList 타입으로 변환된다.

- 중복을 허용하고 순서를 보장한다.

@OneToMany(mappedBy="team")
@OrderColumn(name="POSITION") // DB에서 순서값을 저장할 필드명
private List<Member> members = new ArrayList<Member>();

- 위치 값을 활용해서 List의 메소드를 이용할 수 있다.

list.add(3, member3);
list.get(6);

- @OrderColumn을 사용해서 List의 위치 값을 보관하는 방식은 불편하고 추가적인 UPDATE문이 자주 실행되기 때문에 비효율적이어서 실무에서 잘 사용되지 않는다.

 

 

 

5. @OrderBy

- @OrderColumn이 테이블에 순서용 컬럼을 추가하는 역할을 한다면, @OrderBy는 SQL의 ORDER BY절을 사용해서 컬렉션을 정렬하는 역할을 한다. 즉, 순서용 컬럼을 추가할 필요가 없다.

- 모든 컬렉션에 사용할 수 있다.

@OneToMany(mappedBy="team")
@OrderBy("username desc, id asc") // Member의 username, id 필드를 정렬에 이용
private Set<Member> members = new HashSet<Member>();

※ Hibernate는 Set에 @OrderBy를 적용하면 순서를 유지하기 위해 내부적으로 LinkedHashSet을 사용한다.

- 컬렉션을 조회할 때 내부적으로 쿼리가 실행되면 ORDER BY절에 의해 정렬되어 조회된다.

 

 

 

● 참고자료 : 자바 ORM 표준 JPA 프로그래밍

반응형

댓글