22년 08월 13일

Jang990·2023년 2월 1일
0
post-custom-banner

22년 08월 13일

오늘 한 일

  • DB 테이블 변경
  • 하드코딩된 ID를 MySQL Auto Increment로 부분 변경

JPA n+1 문제

이전에 마주한 문제지만 까먹을까봐 정리해서 적어놓는다.

고양이(Cat)와 주인(Owner) 관계를 생각해보자.

주인은 고양이를 10마리씩 키우고 둘은 양방향 매핑이 되어있다고 가정한다.

다음과 같이 주인을 조회하는 코드를 실행한다면 고양이를 조회하는 쿼리가 10번 호출된다.

List<Owner> everyOwners = ownerRepository.findAll();

이런 현상은 FetchType.EAGER라서 발생하는 것이 아니다. FetchType.LAZY로 설정한다 한들 고양이의 이름을 조회하려 할 때 결국 동일하게 발생한다.

List<Owner> everyOwners = ownerRepository.findAll();
List<String> catNames = everyOwners.stream().flatMap(it -> it.getCats().stream().map(cat -> cat.getName())).collect(Collectors.toList());

FetchType을 변경하는 것은 단지 N+1 발생 시점을 연관관계 데이터를 사용하는 시점으로 미룰지, 아니면 초기 데이터 로드 시점에 가져오느냐에 차이만 있는 것이다.


해결방법은 직접 쿼리 작성, EntityGraph 등등 다양하다. 각각을 확인하고 알맞은 방법을 사용하자.

출처
https://incheol-jung.gitbook.io/docs/q-and-a/spring/n+1



오류: Unable to locate Attribute with the the given name [Column]

JPA Entity 객체의 멤버 변수를 수정한 후 이러한 오류가 나타난다면 변수이름을 제대로 설정했는지 확인해보자.

@Id
String weekId; //올바른 객체명
//String WeekId; //올바르지 않은 객체명

만약 다른 엔티티와 관계가 있는 컬럼을 고쳤을 때 에러가 나타난다면 다음과 같이 @NamedEntityGraphs를 확인해보자.

// String subjectWeekInfo;
String weekInfo; //위에 멤버변수 subjectWeekInfo를 weekInfo로 바꾼 상황

@NamedEntityGraphs({
	@NamedEntityGraph(
			name = "user-own-task",
			attributeNodes = {
					@NamedAttributeNode(value = "userTask", subgraph = "task-detail")
			},
			subgraphs = { @NamedSubgraph(
					name = "task-detail",
					// attributeNodes = { @NamedAttributeNode("subjectTaskInfo") }
					attributeNodes = { @NamedAttributeNode("taskInfo") } 
				)
			}
	),
})


JPA 선호 패턴 관련 글

https://cheese10yun.github.io/jpa-preference/

profile
공부한 내용을 적지 말고 이해한 내용을 설명하자
post-custom-banner

0개의 댓글