4.4 KiB
4.4 KiB
PRD: 관리자 회원 목록 LazyInitializationException 수정
1. Overview
spring.jpa.open-in-view=false 환경에서 관리자 회원 리스트와 크리에이터 리스트 조회 시 Member.signOutReasons lazy collection 접근으로 발생하는 LazyInitializationException을 방지한다.
2. Problem
- 관리자 회원 목록 응답 생성 중
Member.signOutReasons를 읽어 탈퇴일을 계산한다. - 현재
AdminMemberService의 목록 조회 메서드는 트랜잭션 경계가 없어 QueryDSL 조회 후 영속성 컨텍스트가 닫힌 상태에서 lazy collection을 접근할 수 있다. spring.jpa.open-in-view=false환경에서는 이 접근이org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: kr.co.vividnext.sodalive.member.Member.signOutReasons로 이어진다.- 같은 응답 매핑 흐름을 사용하는 관리자 회원 리스트, 회원 검색, 크리에이터 리스트, 크리에이터 검색 모두 같은 위험이 있다.
3. Goals
osiv=false환경에서도 관리자 회원 리스트와 크리에이터 리스트가 예외 없이 응답된다.- 기존 API 응답 스키마와 정렬/필터 조건을 변경하지 않는다.
- 탈퇴 이력이 있는 회원의
signOutDate계산 동작을 유지한다. - 서비스 계층에 명확한 read-only 트랜잭션 기본 경계를 둔다.
- 실패 재현 테스트를 먼저 작성하고, 최소 수정으로 통과시킨다.
4. Non-Goals
- 관리자 회원 목록 API의 응답 필드를 변경하지 않는다.
Member.signOutReasonsfetch 전략을 전역 eager로 바꾸지 않는다.- 목록 조회를 projection 전용 쿼리로 전면 개편하지 않는다.
- pagination/count 쿼리 구조를 리팩터링하지 않는다.
- OSIV 설정을 다시 켜지 않는다.
5. Target Users
- 관리자: 관리자 화면에서 회원 목록과 크리에이터 목록을 조회하는 사용자
- 운영자: 탈퇴 또는 차단 이력이 있는 회원을 포함한 목록을 안정적으로 확인해야 하는 사용자
6. User Stories
- 관리자는 탈퇴 이력이 있는 일반 회원이 포함된 회원 리스트를 조회해도 서버 오류를 만나지 않아야 한다.
- 관리자는 탈퇴 이력이 있는 크리에이터가 포함된 크리에이터 리스트를 조회해도 서버 오류를 만나지 않아야 한다.
- 관리자는 검색 결과에서도 동일하게 탈퇴일과 활성 상태를 확인할 수 있어야 한다.
7. Core Features
Feature A. 관리자 회원 목록 조회 트랜잭션 보강
Requirements
AdminMemberService는 클래스 레벨@Transactional(readOnly = true)로 조회 기본 트랜잭션을 제공한다.AdminMemberService.getMemberList(...)는 read-only 트랜잭션 안에서 조회와 응답 매핑을 완료한다.AdminMemberService.searchMember(...)는 read-only 트랜잭션 안에서 조회와 응답 매핑을 완료한다.AdminMemberService.getCreatorList(...)는 read-only 트랜잭션 안에서 조회와 응답 매핑을 완료한다.AdminMemberService.searchCreator(...)는 read-only 트랜잭션 안에서 조회와 응답 매핑을 완료한다.AdminMemberService.updateMember(...),AdminMemberService.resetPassword(...)는 메서드 레벨@Transactional로 쓰기 트랜잭션을 유지한다.- 기존
processMemberListToGetAdminMemberListResponseItemList(...)의 응답 필드 계산 방식은 유지한다.
Edge Cases
signOutReasons가 비어 있으면 기존처럼signOutDate는 빈 문자열이다.signOutReasons가 있으면 기존처럼 마지막 탈퇴 이력의createdAt을 KSTyyyy-MM-dd HH:mm형식으로 내려준다.authlazy one-to-one 접근도 같은 read-only 트랜잭션 안에서 처리되어야 한다.
8. Technical Constraints
- Kotlin + Spring Boot 2.7.14 + Spring Data JPA 기준으로 구현한다.
- 테스트 환경의
spring.jpa.open-in-view=false설정을 유지한다. - 서비스 클래스에는
@Transactional(readOnly = true)를 사용하고, 쓰기 메서드는 기존 메서드 레벨@Transactional을 유지한다. - 변경 범위는
AdminMemberService와 해당 테스트로 제한한다.
9. Metrics
AdminMemberServiceTest에서 OSIV off 조건의 회원/크리에이터 목록 조회 테스트가 통과한다.- 관련 단일 테스트와
ktlintCheck가 통과한다.