1. N+1 문제 발생 시키고자 하는 테스트 코드로 해당 문제가 발생하지 않는 문제 (해결 X)
발생 상황
- 프로젝트 레벨 2 가 N+1 문제 해결을 위한 리팩토링 문제인데,
- 프로젝트 요구사항은 아니지만 N+1 문제에 대해 직접적으로 확인하여 이해하고자 테스트 코드를 구현 시도
테스트를 위한 기본 세팅
// 테스트 세팅
@Autowired
private TodoRepository todoRepository;
@Autowired
private UserRepository userRepository;
@Autowired
EntityManagerFactory emf;
@BeforeEach
void setUp() {
// User, Todo 5개 생성
for (int i=1; i<=5; i++) {
User user = new User("test" + i + "@email.com", "pw123", UserRole.USER);
userRepository.save(user);
Todo todo = new Todo("테스트 제목" + i, "테스트 내용" + i, "테스트 날씨", user);
todoRepository.save(todo);
}
}
N+1 문제 발생 시키기 위한 테스트 코드
- 기대 결과: 쿼리가 user의 email을 가져올 때 마다 쿼리가 실행되는 것을 기대함
- 구현 결과
- 기대 결과와는 다르게 쿼리를 반복적으로 실행되지 않음을 확인
- 쿼리 수를 확인할 수 있는 코드도 추가하였으나 쿼리 수 2회로 큰 의미가 없었음
// 기존 코드 > 테스트 코드를 위해 코드 삭제 X
@Query("SELECT t FROM Todo t LEFT JOIN t.user u ORDER BY t.modifiedAt DESC")
Page<Todo> findAllByOrderByModifiedAtDesc(Pageable pageable);
/**
* N+1 테스트 -> 에러 발생
*/
@Test
void nPlusOneError() {
// 쿼리 수 확인
SessionFactory sf = emf.unwrap(SessionFactory.class);
sf.getStatistics().setStatisticsEnabled(true);
System.out.println("===== N+1 문제 발생 테스트 =====");
Page<Todo> todos = todoRepository.findAllByOrderByModifiedAtDesc(PageRequest.of(0,5));
for (Todo todo : todos) {
System.out.println("제목: " + todo.getTitle());
System.out.println("유저이메일: " + todo.getUser().getEmail());
}
System.out.println("쿼리 실행 수: " + sf.getStatistics().getPrepareStatementCount());
System.out.println("===== N+1 문제 발생 테스트 종료 =====");
}
회고
- 시간이 부족해서 해당 테스트 코드를 개선하지 못하였다.
- 아직까지 N+1 문제에 대해 정확히 이해를 하지 못하였다.
- 조금 더 공부가 필요함을 느꼈다.
'Sparta > Projects' 카테고리의 다른 글
[Project] Spring - Plus 개인 과제 트러블 슈팅 (0) | 2025.07.04 |
---|---|
[Project] CRUD 코드 개선 (2) | 2025.06.12 |
[Project] 일정 관리 앱 Develop 하기 (with JPA) (0) | 2025.05.26 |
[Project] 일정 관리 앱 만들기 (0) | 2025.05.14 |
[Project] 키오스크를 만들어보자 (0) | 2025.05.01 |