인프런 커뮤니티 질문&답변

안채연님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발

엔티티 설계시 주의점

엔티티에서 equals 오버라이딩, fetch join 2번 질문

해결된 질문

24.06.13 18:10 작성

·

94

0

게시글이 여러 댓글과 이미지를 가지고 있는 경우 게시글을 조회할 때 댓글과 이미지를 한번에 조회하는 것을 구현하고 있었습니다.

 

@SpringBootTest
@Transactional
@Rollback(value = false)
class PostRepositoryTest {

    @Autowired PostRepository postRepository;
    @Autowired UserRepository userRepository;
    @Autowired CommentRepository commentRepository;
    @Autowired ImageRepository imageRepository;
    @Autowired EntityManager em;

    @Test
    void 게시글조회시_댓글_이미지_함께_조회() {

        User user = User.builder()
                .username("tester")
                .password("password")
                .build();
        userRepository.save(user);

        Post post = Post.builder()
                .title("테스트제목")
                .content("테스트내용")
                .build();
        postRepository.save(post);

        Comment comment = Comment.builder()
                .post(post)
                .user(user)
                .content("댓글입니다.")
                .build();
        commentRepository.save(comment);

        Image image = Image.builder()
                .image("/file/test")
                .post(post)
                .build();
        imageRepository.save(image);

        em.flush();
        em.clear();
        Post findPost = postRepository.findByIdWithCommentsAndImages(post.getId()).get();

        assertThat(findPost.getId()).isEqualTo(post.getId());
        assertThat(findPost.getTitle()).isEqualTo("테스트제목");
        System.out.println(findPost.getComments().get(0).getContent());
        assertThat(findPost.getComments()).contains(comment);
    }

}

    @Query("select p from Post p " +
            "left join fetch p.comments " +
//            "left join fetch p.images " +
            "where p.id = :id")
    Optional<Post> findByIdWithCommentsAndImages(@Param("id") Long id);
  1. 우선 OneToMany에서 fetch join을 2번하면 에러가 나더라구요 이 경우에 그럼 Comments와 Images를 따로 fetch join해서 가져와야하나요?

  2. 테스트에서 em.flush(); em.clear(); 하면 assertThat(findPost.getComments()).contains(comment);여기서 테스트 fail을 합니다. 영속성에서 제거가 돼서 그런 것 같은데 em.flush를 안하고 테스트를 해도 의미가 있는 건지 궁금합니다. 만약 em.flush를 해야지 의미 있다면 equals와 hashcode를 id값으로 오버라이딩을 해야하나요?

  3. 강의를 다 듣고 프로젝트에 적용해보려니까 여러군데에서 막히네요.. 개념이 부족한 거겠죠?

답변 1

0

y2gcoder님의 프로필 이미지

2024. 06. 14. 09:11

안녕하세요. 안채연님, 공식 서포터즈 y2gcoder입니다.

  1. 컬렉션 페치 조인은 하나만 허용합니다! 나머지는 batchsize를 통해 가져오시는 것을 추천합니다! 이러한 성능 최적화와 관련된 부분을 설명해주는 활용 2편 강의를 수강하시는 것을 정말 추천합니다 🙂

  2. 말씀하신대로 영속성 컨텍스트 내에서만 엔티티 간의 동일성을 보장해주기 때문에 테스트 에러가 발생한 것으로 보입니다! 이 때는 두 엔티티의 id값을 비교하시는 것을 추천합니다. id가 동일하면 두 엔티티는 동일하다고 할 수 있습니다 🙂 id는 엔티티의 식별자에 해당하기 때문입니다.

  3. 저도 실무나 프로젝트를 진행하다 보면 강의에서 들은 내용을 적용해보기도 하고, 잊어버렸던 내용을 다시 복습하기도 하는 것 같습니다. 그때마다 저는 영한님께서도 늘 말씀하시는 학습의 3단계 중 체화를 하고 있는게 아닌가 하며 학습을 하고 있는 순간이라 생각하고 있습니다! 저는 좋은 순간이라고 생각합니다! 파이팅입니다!

 

감사합니다.

안채연님의 프로필 이미지
안채연
질문자

2024. 06. 14. 17:06

답변 감사합니다!! 좋은 순간이라 생각하고 프로젝트에 계속 적용해보겠습니다!