2023-01-13-TIL
2023-01-13-TIL
Today I Learned
JPA 연관관계를 어디까지 매핑할지, 매핑한다면 어떤 방식이 안전하고 성능에 유리한지를 찾아봤다.
JPA Association Pros and Cons
연관관계를 엔티티 참조로 매핑하면 객체 그래프 탐색과 JPQL 조인이 편해지고, 영속성 전이(cascade)나 고아 객체 제거 같은 기능을 쓸 수 있다. 반면 엔티티 사이의 결합이 강해지고, 지연 로딩 프록시와 N+1 문제, 양방향 관계의 동기화 같은 관리 부담이 생긴다. 연관관계 없이 외래 키 값(ID)만 필드로 두면 엔티티가 단순해지고 모듈 경계를 나누기 쉽지만, 조인이 필요한 조회는 직접 쿼리로 풀어야 한다. 링크된 질문은 DB에 외래 키 제약을 걸지 않은 채 매핑만 하는 경우의 장단점을 다룬다.
- https://stackoverflow.com/questions/17928152/hibernate-pros-cons-of-association-mapping-without-foreginkey
JPA Hypersistence Optimizer
Vlad Mihalcea가 만든 Hypersistence Optimizer는 JPA와 Hibernate 매핑과 설정을 분석해 잘못된 사용을 자동으로 찾아 주는 상용 도구다. 소개 페이지의 예시는 @ManyToOne 연관관계가 기본 EAGER 페치 전략을 쓰고 있다는 사실을 찾아내는 것이다. 함께 링크한 Association Fetching Validator는 영속성 컨텍스트에서 N+1 패턴처럼 보이는 연관 엔티티 로딩을 감지하는 기능이다.
- https://vladmihalcea.com/hypersistence-optimizer/
- https://vladmihalcea.com/jpa-association-fetching-validator/
JPA Association Best Practices
자주 언급되는 권장 사항을 모으면 다음과 같다.
@ManyToOne을 기본으로 쓴다. 외래 키를 가진 자식 쪽에 매핑하는 것이 테이블 구조와 가장 자연스럽게 맞는다. Vlad Mihalcea 글은@ManyToOne의 기본 페치 전략이 EAGER라서FetchType.LAZY를 명시하라고 강조한다.- 다대다는
List대신Set으로 매핑한다. Thorben Janssen 글에 따르면List로 매핑한@ManyToMany에서 원소 하나를 지우면 Hibernate가 연결 테이블의 해당 행을 모두 지운 뒤 남은 행을 다시 넣는다. - 양방향 관계라면 양쪽 컬렉션을 함께 갱신하는 동기화 메서드(
addAuthor,removeAuthor)를 엔티티에 둔다. JPA Buddy 글이 이 메서드를 다대다에서 작성하는 방법을 다룬다. - 다대다에
CascadeType.REMOVE를 걸지 않는다. 한쪽을 지울 때 다른 엔티티와도 연결된 반대편까지 지워질 수 있다.
1
2
3
4
5
6
7
8
9
10
@Entity
public class Book {
@ManyToMany
private Set<Author> authors = new HashSet<>();
public void addAuthor(Author author) {
authors.add(author);
author.getBooks().add(this);
}
}
- https://www.jpa-buddy.com/blog/synchronization-methods-for-many-to-many-associations/
- https://thorben-janssen.com/ultimate-guide-association-mappings-jpa-hibernate/
- https://thorben-janssen.com/best-practices-for-many-to-many-associations-with-hibernate-and-jpa/
- https://medium.com/@vaqifagayev/associations-spring-jpa-d58988c85da3
- https://vladmihalcea.com/manytoone-jpa-hibernate/
- https://www.youtube.com/watch?v=808pWqjuhMo
JPA Association Performance Tuning
Thorben Janssen의 “고성능 애플리케이션에서 피해야 할 Hibernate 매핑 6가지”는 EAGER 페치, List로 매핑한 다대다, 양방향 일대일, @Formula, @OrderBy, 큰 연관관계의 CascadeType.REMOVE를 꼽는다. 여기에 더해 연관 엔티티를 함께 써야 하는 조회는 페치 조인이나 @EntityGraph로 한 번에 가져오고, 많은 자식을 저장할 때는 JDBC 배치 설정(hibernate.jdbc.batch_size)을 켜는 것이 일대다 저장 성능을 높이는 일반적인 방법이다.
- https://stackoverflow.com/questions/44072550/jpa-how-to-improve-performance-in-persistance-of-onetomany-relationships
- https://thorben-janssen.com/6-performance-pitfalls-when-using-spring-data-jpa/
- https://thorben-janssen.com/6-hibernate-mappings-you-should-avoid-for-high-performance-applications/
- https://www.adservio.fr/post/hibernate-performance-best-practices
- https://blog.ippon.tech/boost-the-performance-of-your-spring-data-jpa-application/
Todo
- 트랜잭션 매니저 정리하기
- 트랜잭션 격리수준 정리하기
- Transaction Propagation 정리하기
- R2DBC 정리하기
댓글
아직 댓글이 없습니다