쌓고 쌓다

테스트 코드에서 QueryDSL 쿼리 결과가 이상할때 본문

프로그래밍/spring

테스트 코드에서 QueryDSL 쿼리 결과가 이상할때

승민아 2024. 3. 18. 21:02

게시글, 게시글 좋아요, 회원 테이블이 관계를 맺고있는 상황이다.

 

이때 다음과 같이 임시 데이터를 생성하고 필요한 필드들만 관계 매핑을하고 QueryDSL로 쿼리를 날렸다.

//given
Member posterLiker = new Member();
memberRepository.save(posterLiker);

Poster poster1 = new Poster();
Poster poster2 = new Poster();
posterRepository.save(poster1);
posterRepository.save(poster2);

PosterLike posterLike1 = new PosterLike();
posterLike1.setPoster(poster1);
posterLike1.setMember(posterLiker);
posterLikeRepository.save(posterLike1);

PosterLike posterLike2 = new PosterLike();
posterLike2.setPoster(poster2);
posterLike2.setMember(posterLiker);
posterLikeRepository.save(posterLike2);

 

작성한 쿼리는 다음과 같이 내가 좋아요 누른 게시글들의 정보를 뽑아내는 쿼리이다.

 

QueryDSL은 다음과 같다.

List<PosterResponse> posters = jpaQueryFactory
    .select(new QPosterResponse(
        poster.id,
        poster.writer.id,
        poster.writer.name,
        ...
    ))
    .from(posterLike)
    .leftJoin(poster).on(poster.id.eq(posterLike.poster.id))
    .where(posterLike.member.id.eq(memberId))
    .orderBy(posterLike.regDate.desc())
    .limit(pageable.getPageSize())
    .offset(pageable.getOffset())
    .fetch();

JPAQuery<Long> countQuery = jpaQueryFactory
    .select(poster.count())
    .from(posterLike)
    .leftJoin(poster).on(poster.id.eq(posterLike.poster.id))
    .where(posterLike.member.id.eq(memberId));

System.out.println("posters = " + posters.size());
System.out.println("countQuery = " + countQuery.fetchOne());

하지만 원하는 결과는 안나와서 마지막에 posters와 countQuery의 크기를 출력해봤다.

 

posters = 0
countQuery = 2

countQuery를 통해 원하는 값은 나오는데 posters의 개수는 또 카운트 쿼리와 다르다...

분명 같은 조인과 조건절을 사용했음에도 불구하고..

 

실제 날아간 쿼리를 보자.

poster_like와 poster는 LEFT JOIN을 하고

그 결과에 member 테이블과 INNER JOIN을 한다. 이떄 poster 테이블의 member_id 외래키와 조인을 한다.

 

생각해보니... 내가 좋아요 누른 게시글들의 정보를 응답으로 줄때

해당 게시글의 작성자의 정보도  포함되어 있었다. 그러니 Poster의 작성자 외래키를 NULL로 설정하면 안됐었다..

특히 INNER JOIN을 해버리는데 게시글의 작성자가 NULL이라 더더욱 쿼리의 결과에서 제외된것 이였다...

 

 

//given
Member posterLiker = new Member();
memberRepository.save(posterLiker);

Poster poster1 = new Poster();
poster1.setWriter(member); // 추가된 라인
Poster poster2 = new Poster();
poster2.setWriter(member); // 추가된 라인

임시 데이터를 생성해서 테스트 코드를 돌려볼때 데이터를 잘 생성해야한다...

Comments