배경
- 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 메소드를 사용하는 것이 안정적이라서 유지보수하기 좋을 것 같다