JPA
-
N+1 Select 문제JPA 2023. 2. 14. 02:29
N+1 문제란, 연관 관계에서 발생하는 이슈로 연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오게 된다. 이를 N+1 문제라고 한다. N+1이 발생하는 이유는? jpaRepository에 정의한 인터페이스 메서드를 실행하면 JPA는 메서드 이름을 분석해서 JPQL을 생성하여 실행하게 된다. JPQL은 SQL을 추상화한 객체지향 쿼리 언어로서 특정 SQL에 종속되지 않고 엔티티 객체와 필드 이름을 가지고 쿼리를 한다. 그렇기 때문에 JPQL은 findAll()이란 메소드를 수행하였을 때 해당 엔티티를 조회하는 select * from Owner 쿼리만 실행하게 되는것이다. JPQL 입장에서는 연관관계 데이터를 무시하고 해당 엔티..
-
@EntityGraphJPA 2023. 2. 14. 02:05
연관관계가 있는 엔티티를 조회할 경우 지연 로딩으로 설정되어 있으면 연관관계에서 종속된 엔티티는 쿼리 실행 시 select 되지 않고 proxy 객체를 만들어 엔티티가 적용시킨다. 그 후 proxy 객체를 호출할 때마다 그때그때 select 쿼리가 실행된다. 위와 같은 연관관계가 지연로딩으로 되어있을 경우 fetch 조인을 사용하여 여러 번의 쿼리를 한번에 해결할 수 있다. @EntityGraph는 Data JPA 에서 fetch 조인을 어노테이션으로 사용할 수 있도록 만들어 준 기능이다. 엔티티들은 서로 연관되어 있는 관계가 보통이며 이 관계는 그래프로 표현이 가능하다. EntityGraph는 JPA가 어떤 엔티티를 불러올 때 이 엔티티와 관계된 엔티티를 불러올 것인지에 대한 정보를 제공한다. Fetc..
-
JPA Enum Type (@Enumerated, EnumType)JPA 2023. 1. 25. 23:08
JPA는 Enum Type과 DB 매핑을 도와준다. 내가 사용한 경우는, 프로젝트에 알람 기능을 추가할 때, 알람의 타입을 구별하기 위해 Enum을 사용하였다. @Entity @Getter @EqualsAndHashCode(of = "id") public class Notification { @Id @GeneratedValue private Long id; private String title; private String message; @ManyToOne private User user; @Enumerated private NotificationType notificationType; Entity로 Enum 타입을 사용하고 싶다면 @Enumerated 어노테이션이 필요하다. public enum Not..
-
@ManyToMany 사용 시 주의할 점 (List, Set)JPA 2023. 1. 25. 16:35
@ManyToMany 사용을 되도록 피해야 한다고 배웠다. 그 이유는, 개발하다 보면 연결 테이블이 단순히 연결만 하고 끝나지 않는다. 조인 테이블 자체에 주문 시간, 수량 같은 추가 데이터가 많이 들어갈 수 있다. 하지만, 매핑 정보만 넣는 것이 가능하고, 추가 정보를 넣는 것 자체가 불가능하다. 그리고 중간 테이블이 숨겨져 있기 때문에 예상하지 못하는 쿼리들이 나간다. 이러한 문제점들 때문에 실무에서는 사용하면 안된다고 한다. 해결 방법으로는, 연결 테이블용 엔티티를 추가한다. 사실상 연결 테이블을 엔티티로 승격시킨다. 그리고 @ManyToMany를 각각 일대다, 다대일로 관계를 맺어준다. JPA가 만들어주는 숨겨진 매핑테이블의 존재를 밖으로 꺼내는 것이다. 등이 있다. 나는 그럼에도 다대다 관계를 ..
-
JPA의 리턴타입이 Optional인 이유JPA 2023. 1. 19. 23:17
다음과 같이 JPA에서 제공하는 findById 메소드를 이용하여 해당하는 StudyGroup을 가져오려고 하였는데, 컴파일 에러가 나타났다. 아래 처럼 Optional로 리턴타입을 감싸줌으로써 컴파일 에러를 해결할 수 있다. 원인은 CrudRepository 인터페이스에 있다. Repository 인터페이스를 만들 때 JPA를 사용하기 위해 JpaRepository를 상속받는다. JpaRepository 인터페이스의 find와 관련된 메서드에는 CrudRepository 를 확인하라고 적혀있다. CrudRepository 인터페이스의 findById 메서드를 확인해보면 리턴값이 Optional로 고정되어있다. Optional을 사용하면 좋은 점이 무엇이 있을까? Optional은 반복적인 null 처리..