[JPA] FetchType.EAGER의 남용과 순환 참조 그리고 N+1

2024. 6. 20. 11:15JPA

# N+1 문제에 대한 해결방안을 다룬 글이 아닙니다.  

 

FetchType.EAGER를 남용했다. 

@OneToMany @ManyToOne 관계를 지정할 때도, 하나의 엔티티 클래스 안에서 EAGER 속성을 여러 번 사용하는 등. 서버 실행 자체가 되지 않는 문제가 발생했다. 단순히 문제를 해결하기 위해 방법을 찾아나섰고

 

public class MemberVO {
	
	@Id
	private String member_id;
	
	@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	@JoinColumn(name="chat_no")
        private ChatVO chatVO;
	
	@OneToMany(mappedBy = "memberVO",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	private List<PlanVO> planVO = new ArrayList<>();
	
	@OneToMany(mappedBy = "memberVO",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	private List<Community_boardVO> community_boardVO = new ArrayList<>();

 

EAGER >> LAZY로 수정했다. 

단순히 EAGER가 좋다고 생각했다. JPA에 대해 무지(이렇게 알아가는 거겠지...)하면서 단순히 Member를 조회할 때 CHAT, PLAN, BOARD를 사용해야 하니 EAGER를 쓰면 되겠지. 

 

단순히 성능 저하를 일으키며 예상치 못한 여러 개의 추가 쿼리를 날리는 N+1 문제였다면 나는 계속 EAGER 속성을 모르고 사용했을 지도 모른다... 하지만 내 경우엔 EAGER 속성으로 맺어진 두 개의 테이블이 서로를 계속 참조하면서 발생한 순환 참조 문제, 데이터베이스 연결이 과도하게 사용되어 커넥션 풀 고갈, 타임아웃 문제였다. 

 

N+1 문제를 겪은 많은 사람들이 말하길, 대부분 LAZY를 사용하고 Fetch Join을 비롯해 여러 방법으로 추가 쿼리 생성을 막을 수 있다고 한다. 실제 N+1 문제를 겪고 해결 방안을 적용해봐야겠다.