Querydsl/JPA에서 Exposed DSL로 옮기며 kapt를 걷어낸 이유
Querydsl/JPA 기반 persistence를 Exposed DSL로 옮긴 작업은 단순한 ORM 교체가 아니었습니다. Kotlin 빌드에서 kapt와 생성 코드를 걷어내고, persistence 경계를 더 명시적으로 만든 전환이었습니다.
Tag
Querydsl/JPA 기반 persistence를 Exposed DSL로 옮긴 작업은 단순한 ORM 교체가 아니었습니다. Kotlin 빌드에서 kapt와 생성 코드를 걷어내고, persistence 경계를 더 명시적으로 만든 전환이었습니다.
Native Query를 Kotlin JDSL로 마이그레이션하면서 확장 함수 패턴을 도입했습니다. 일반 join을 fetchJoin으로 변경하여 N+1 쿼리 문제를 해결하고, 데이터베이스 레벨에서 직접 집계 연산을 수행하여 쿼리 성능을 개선했습니다. Kotlin JDSL의 타입 안전성과 확장 함수 패턴을 활용하여 유지보수성을 크게 향상시켰습니다.
HikariCP 대시보드에서 Connection Timeout이 27회 발생하는 문제를 발견했습니다. 원인은 N+1 쿼리 문제와 작은 Connection Pool 크기였습니다. 배치 조회로 N+1 쿼리를 해결하고 Connection Pool 크기를 5에서 20으로 증가시켜 Timeout을 0으로 만들었습니다. 쿼리 수는 161개에서 3개로 98% 감소했습니다.
Spring Boot와 Hibernate를 사용하여 PostgreSQL의 jsonb 타입을 다룰 때 발생하는 타입 불일치 문제를 해결한 경험을 공유합니다. hypersistence-utils 라이브러리를 활용해 간단하고 안전하게 jsonb 컬럼을 Map 타입으로 매핑하는 방법을 설명합니다.
Spring의 @Transactional 어노테이션은 선언적 트랜잭션 관리 기능을 제공하며, Propagation 옵션을 통해 트랜잭션의 동작 방식을 설정할 수 있다. 주요 Propagation 옵션으로는 REQUIRED, REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED, NEVER, NESTED가 있으며, 각 옵션은 트랜잭션의 참여 및 생성 방식에 따라 다르게 작동한다. 실제 프로젝트에서의 활용 예시와 성능 최적화 팁도 포함되어 있으며, AOP 프록시 패턴을 기반으로 내부 구현 원리를 설명한다.
JPA에서 지연 로딩과 JOIN FETCH의 차이를 설명하며, 과제 취소 기능 구현을 통해 성능 비교를 진행했다. 지연 로딩은 필요할 때 데이터를 로딩하는 반면, JOIN FETCH는 연관된 엔티티를 한 번의 쿼리로 조회하여 성능을 개선한다. 실제 성능 측정 결과, JOIN FETCH를 사용했을 때 약 32-43%의 성능 향상이 있었다. 조건부로 사용되는 연관 엔티티에는 지연 로딩을, 항상 함께 사용되는 경우에는 JOIN FETCH를 사용하는 것이 바람직하다.