본문 바로가기

JAVA/- Spring

[spring boot] @ManyToOne에서 데이터 선택적으로 가져오기

Team과 Member 엔티티가 있습니다.

하나의 Member는 여러개의 Team을 가질 수 있습니다. 

Fetch를 Lazy형태로 받아옵니다. => Member객체를 선택하면 1개의 쿼리문이 나오고 순수한 Member 요소들(id, name)만 가져오겠다는 뜻입니다.

 

findAll()을 해서 JSON형태로 반환하려 하는데 

proxy 객체를 찾을 수 없다는 에러가 뜹니다. 

사실 LAZY로 Team객체를 찾개 되면 처음에 proxy를 담아둡니다. 즉, 본래 객체가 아니라 가짜 객체를 담아둔것입니다. 

그리고 다시 DB에서 select해서 진짜 Team객체를 싹 바꿔주는 것이죠

그런데 Lazy상태이니 select는 해오지 못하고 proxy상태로 json으로 바뀌려고 하니깐 에러가 뜨는 것입니다. 

 

해결방법

DTO를 사용합니다!

modelMapper로 List<Member> -> List<MemberDTO>로 변경했습니다. 

ModelMapper를 사용하려면 아래 dependency를 추가해야 합니다. 

implementation 'org.modelmapper:modelmapper:2.4.2'

이러면 어디상 Team을 Json으로 바꾸려고 하지 않습니다.

쿼리도 1개가 발생합니다.

 

 

 

Member랑 Team정보 둘다 필요한데 쿼리는 1번만 하게 하는 법

@NamedEntityGraph 어노테이션을 이용합니다. 

attributeNodes는 Member를 조회할 때 가지고 오고 싶은 연관관계를 적어줍니다. (여기서는 team 객체입니다.)

 

@EntityGraph 어노테이션을 붙혀주기 위해 Repository 인터페이스에 가서 findAll()을 재정의 해줍니다. 

아까 만든 EntityGraph를 사용하기위해 적어주는 것입니다. 이러면 Join쿼리가 알아서 발생합니다. Member와 Team간의 Join이 발생합니다. 

이렇게 left outer join으로 team을 가져옵니다.

 

728x90