bong-u/til

Spring - JPA : getReferenceById vs findById

수정일 : 2024-11-15

배경

  • Service layer에서 createPost 메소드를 구현하는 중 이었다
  • Post entity는 User entity와 ManyToOne 관계이다
  • User entity를 가져오는 방식에 따라 두가지 방식의 구현이 가능했다
  • 두 방식의 장단점을 파악해보았다

getReferenceById 사용

 1public Post createPost(PostDTO.Request postDTO, int userId) {
 2    // 프록시 객체를 가져온다
 3    User user = userRepository.getReferenceById(userId);
 4
 5    Post post = Post.builder()
 6            .title(postDTO.getTitle())
 7            .content(postDTO.getContent())
 8            .created_at(LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS))
 9            .author(user)
10            .build();
11
12    try {
13        return postRepository.save(post);
14    } catch (DataIntegrityViolationException e) {
15        throw new EntityNotFoundException("해당 유저가 없습니다.");
16    }
17}
  • 장점 : 쿼리 한번으로 Post entity를 생성할 수 있다
  • 단점 : insert 쿼리 실행 중 발생한 예외를 잡기 때문에 안정적이지 않다

findById 사용

 1public Post createPost(PostDTO.Request postDTO, int userId) {
 2    // 실제 객체를 가져온다
 3    Optional<User> user = userRepository.findById(userId);
 4
 5    if (user.isEmpty())
 6        throw new EntityNotFoundException("해당 유저가 없습니다.");
 7
 8    Post post = Post.builder()
 9            .title(postDTO.getTitle())
10            .content(postDTO.getContent())
11            .created_at(LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS))
12            .author(user.get())
13            .build();
14
15    return postRepository.save(post);
16}
  • 장점: insert 쿼리 실행 전에 미리 예외를 처리하기 때문에 안정적이다
  • 단점: 쿼리 두번으로 인한 성능 저하가 발생한다

결론

  • 쿼리를 두 번 날리더라도 findById 메소드를 사용하는 것이 안정적이라서 유지보수하기 좋을 것 같다