New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BE] QueryDSL을 적용한다 #421
Comments
queryDSL 트러블슈팅
QueryDslConfig.class@Configuration
public class QueryDslConfig {
@PersistenceContext
private EntityManager em;
@Bean
public JPAQueryFactory init() {
return new JPAQueryFactory(em);
}
} MemberRepositoryImpl.class@RequiredArgsConstructor
public class MemberRepositoryImpl implements MemberRepositoryCustom {
private final JPAQueryFactory queryFactory;
@Override
public Optional<Long> findMemberIdByPlatformAndPlatformId(final Platform platform, final String platformId) {
return Optional.ofNullable(queryFactory
.select(member.id)
.from(member)
.where(member.platform.eq(platform).and(member.platformId.eq(platformId)))
.fetchOne());
}
} 결과Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberRepositoryImpl' defined in file [/Users/kth990303/Desktop/woowacourse/2022-nae-pyeon/backend/build/classes/java/main/com/woowacourse/naepyeon/repository/member/MemberRepositoryImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
... 86 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)
... 104 more [Spring Boot에 QueryDSL을 사용해보자](https://tecoble.techcourse.co.kr/post/2021-08-08-basic-querydsl/) 해결 방법
|
findByXXXId 의 쿼리 성능 개선연관관계가 있을 경우 특정 엔티티가 아닌 엔티티의 id로 조회하면 join절이 나간다. 따라서 성능 상으로 좋지 않다.
List<TeamParticipation> findByTeamId(final Long teamId); → XXX의 식별자로 조회하므로 XXX 테이블을 조인해서 가져온다. Spring Data JPA의 기능으로 JPQL이 의도치 않게 추가적으로 호출해서 사용되는 것.
@Override
public List<TeamParticipation> findByTeamId(final Long teamId) {
return queryFactory
.selectFrom(teamParticipation)
.where(isTeamIdEq(teamId))
.fetch();
} → 정상적으로 참고[[Spring Data JPA] findByXXXId 는 불필요한 join을 유발한다](https://velog.io/@ohzzi/Data-Jpa-findByXXXId-%EB%8A%94-%EB%B6%88%ED%95%84%EC%9A%94%ED%95%9C-join%EC%9D%84-%EC%9C%A0%EB%B0%9C%ED%95%9C%EB%8B%A4) |
해당 회원이 작성한 메시지 목록 조회하는 쿼리 개선
return queryFactory
.select(makeProjections()) // DTO 만들기
.from(message)
.join(teamParticipation).on(message.rollingpaper.team.id.eq(teamParticipation.team.id))
.where(isAuthorIdEq(authorId)
.and(message.rollingpaper.member.id.isNull()
.or(message.rollingpaper.member.id.eq(teamParticipation.member.id))
)
)
.distinct();
|
기능 상세
MessageRepository
를 제외한 레포지토리는 custom repository impl 로 factory를 들고 있도록MessageRepository
는 JPAQueryFactory를 들고 있는 클래스 생성 -> 바로 DTO로 변환해서 특수한 상황에서만 쓰이기 때문에 별도의 custom repository로 사용 (엔티티로 뽑으면 N+1 문제 발생)The text was updated successfully, but these errors were encountered: