본문 바로가기
Back-End/Spring

연관관계를 설정하기 위해 필요한 id값을 알고 있다면 객체를 굳이 select할 필요가 있나? (쿼리 줄이기, getReferenceById)

by 우인입니다 2023. 10. 24.

고민

기존 구현 사항

Reply객체를 생성하기 위해 필요한 외래키는 User, Quiz이다.

User : @AuthenticationPrincipal 을 통해 이미 가져온 User객체를 바로 활용 가능하다.

Quiz : PathVariable을 통해 Id값은 이미 알고 있는 상황.

 

 

고민점

위 코드처럼 퀴즈 객체를 불러와서 Reply에 넣어줘야 연관관계가 적용이 될텐데, 이후 Quiz객체는 사용되는 곳이 없다.

실제로 위 코드대로 Reply를 Create하는 api를 실행해보면 실행된 쿼리는 아래와 같다.

 

Quiz객체 Select 쿼리 / Reply객체 Insert 쿼리

 

이는 이미 알고있는 id값을 이용해 굳이 퀴즈 객체를 가져와 id 값만 쓰는 느낌이다.

Quiz객체가 존재하는 지 체크를 해주는 의미가 있다한들, Select 쿼리가 낭비되는 느낌이다.

 

 

 

개선 점

getOne메소드(Deprecated)

getReferenceById( ) 메소드를 통해 Quiz 객체를 가져온다.

 

이는 지연로딩을 통해 Proxy객체만을 갖고 있다가 실제 값이 필요할 때 Select가 일어난다.

지금과 같은 상황에서는 id값을 조회하기 위해서는 Select쿼리를 날릴 필요가 없다.

 

이렇게 코드를 변경한 후 다시 동작시켜 보았다.

 

 

위처럼 Select 쿼리 없이 Insert쿼리문이 발생한 것을 확인할 수 있다.

 

 

보완해야할 점

getReferenceById를 통해 가져온 프록시 객체가 존재하지 않는 경우에 대한 예외처리가 필요해 보인다.

 

(24/06/17 추가)

임의로 존재하지 않는 ID값을 넣어줬다.

 

아래와 같은 예외를 발생시키며 트랜잭션은 종료된다.

 

 

 

참고링크

https://jgrammer.tistory.com/entry/JPA-%EB%B9%84%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9D%B8-%EC%97%B0%EA%B4%80-%EA%B4%80%EA%B3%84-%EC%A0%80%EC%9E%A5-%EB%B0%A9%EC%8B%9D-%EA%B0%9C%EC%84%A0%EB%B6%88%ED%95%84%EC%9A%94%ED%95%9C-select%EB%AC%B8-%EC%A0%9C%EA%B1%B0

https://passionfruit200.tistory.com/386