JPA

JPA

[JPA] 실무에서 만난 N+1 문제 해결하기 (feat. LazyInitializationException)

1. 개요 운영 과정에서 프론트에서 쿠폰 관련 API 호출 시 간헐적으로 타임아웃이 발생한다는 리포트가 들어왔다. APM을 통해 좀 더 면밀히 살펴보니 오라클 쿼리가 비정상적으로 많이 발생하고 있음을 확인할 수 있었다. 발급된 쿠폰을 조회하는 과정에서 N+1 문제와 leftjoin의 잘못된 사용으로 인한 데이터 뻥튀기가 발생하면서 쿠폰 정책에 대한 조회가 불필요하게 이뤄진 게 화근이었다. 데이터 뻥튀기가 되는 문제는 원인이 분명했지만, N+1 문제는 의아했다. 분명 Lazy Loading을 걸어놨는데, 왠지 모르게 Eager Loading이 발생했다. 물론 Lazy Loading을 건다고 해서 N+1 문제가 모두 해결되는 것은 아니지만, 적어도 쿠폰 정책을 참조하지 않는 경우엔 N+1이 발생하지 않았어야..

JPA

[JPA] StoredProcedureQuery execute와 executeUpdate 차이 및 사용법

1. 개요 앞서 executeUpdate를 사용하면서 발생했던 문제에 대한 포스트를 올렸다. 이 문제 자체는 @Transactional 어노테이션을 붙여 트랜잭션을 적용하는 것으로 간단하게 해결했지만, 트랜잭션을 적용하지 않고도 잘 실행되던 SP 쿼리들이 있었기에 특정 쿼리에서만 에러가 발생하는 원인을 좀 더 찾아봤다. 그 원인은 executeUpdate의 내부에 있었다. 2. JDBC의 execute와 executeUpdate, 그리고 executeQuery 먼저 보편적으로 사용되는 JDBC의 execute, executeQuery, execueUpdate에 대해 간단하게 알아보자. 1) execute 모든 종류의 쿼리를 실행하는 데 사용된다 Boolean 값을 반환한다 SELECT 쿼리를 통해 Res..

JPA

[JPA] 스프링 데이터 JPA의 JpaRepository 구현체 분석

JpaRepository 인터페이스만 상속받아도 다양한 편의 기능을 제공한다. 항상 당연하게 써왔지만 문득 엔티티 매니저의 주입 시점이 궁금하여 관련 강의를 보면서 구현체를 살펴봤다. SimpleJpaRepository가 바로 JpaRepository의 구현체이다. 메서드 내부는 대부분 JPA의 기본 기능을 활용하여 구현되어 있었고, 눈여겨볼 만한 몇가지를 정리했다. 생성자 JpaEntityInformation, EntityManager를 생성자를 통해 주입받는다 클래스 어노테이션 @Repository 스프링 빈으로 등록된다(컴포넌트 스캔의 대상이 된다) 스프링은 JPA, JDBC 등 데이터 접근 계층에 대한 여러 예외를 추상화하여 일관된 예외 계층을 제공하는데, 이러한 장점을 취할 수 있다 @Trans..

JPA

[JPA] 스프링 데이터 JPA에서 조인 컬럼(FK)을 조건으로 쿼리 메서드 만들 때 주의사항

개요 Spring Data JPA를 사용하면 간단한 쿼리는 쿼리 메서드로 해결할 수 있다. 관계를 맺고 있는 Entity의 ID(=조인 컬럼, FK)를 알고 있을 때, 바로 해당 ID로 Entity를 조회하는 방식으로 쿼리 메서드를 작성하고 싶을 수 있다. 즉, 성능향상을 위해 두 번째 방법을 선택한다는 것이다. (1) Entity A ID로써 Entity A 조회 -> Entity A로 Entity B 조회 (2) Entity A ID로써 Entity B 조회 그러나 조인 컬럼을 이용하여 쿼리 메서드를 만들 때는 의도치 않은 OUTER JOIN이 발생할 수 있으므로 주의해야 한다. 예제 User와 다대일 관계를 맺고 있는, 즉 user_no를 FK로 갖고 있는 Admin이 있다. Admin public..

코택
'JPA' 카테고리의 글 목록