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

안채연님의 프로필 이미지
안채연

작성한 질문수

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

엔티티 설계시 주의점

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

해결된 질문

작성

·

110

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입니다.

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

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

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

 

감사합니다.

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

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

안채연님의 프로필 이미지
안채연

작성한 질문수

질문하기