728x90
지금까지는 친절한 JPA 덕분에 쿼리에 대한 고민없이 편하게 쿼리 메서드를 이용해서 DB를 조회했었는데,
이번 프로젝트에서는 쿼리 성능 최적화와 쿼리 공부를 목적을 위해 QueryDSL을 사용해보기로 했다.
JPQL은 맨땅에서 작성해야되는 느낌이라 막막했다면 QueryDSL은 문법을 자동 완성해주고 직관적이어서 요리조리 쿼리를 짜볼 수 있어서 좋았다.
처음으로 직접 짠 쿼리로 DB 슬라이스 Test를 진행하려는데 아래 에러를 만났다.
NoSuchBeanDefinitionException: No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
@DataJpaTest
class ChallnegeStatusRepositoryTest {
@Autowired
private ChallengeRepository challengeRepository;
@Test
void findAuthsByChallengeId() throws Exception {
// given
Challenge challenge1 = Challenge.builder().build();
Challenge challenge = challengeRepository.save(challenge1);
Auth auth1 = Auth.builder().challenge(challenge).build();
Auth auth2 = Auth.builder().challenge(challenge).build();
Auth auth3 = Auth.builder().challenge(challenge).build();
authRepository.save(auth1);
authRepository.save(auth2);
authRepository.save(auth3);
challengeRepository.save(challenge);
// when
Tuple auths = challengeRepository.findAuthsByChallengeId(challenge.getChallengeId());
// then
assertEquals(3, auths.size());
}
}
원인
에러 내용을 읽어보면 JPAQueryFactory가 Bean 등록이 되지 않았다고 한다. 이유가 뭘까?
@SpringBootTest를 사용하면 모든 Bean을 등록해주지만 나는 슬라이스 테스트를 진행했기 때문에 @DataJpaTest 애너테이션을 사용했다.
@DataJpaTest는 별도의 Bean을 등록하지 않고 Entity와 EntityManager만 등록해서 Test를 진행한다.
결론적으로 JPAQueryFactory를 별도로 Bean 등록을 해주어야 한다.
해결 방법
1. TestConfig 클래스를 만들어 JPAQueryFactory을 별도로 Bean 등록해준다.
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@TestConfiguration
public class TestConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory(){
return new JPAQueryFactory(entityManager);
}
}
2. @Import로 Test하려는 클래스에 TestConfig.class를 연결해준다.
@DataJpaTest
@Import(TestConfig.class) // 추가
class ChallnegeStatusRepositoryTest {
@Autowired
private ChallengeRepository challengeRepository;
@Test
void findAuthsByChallengeId() throws Exception {
// given
Challenge challenge1 = Challenge.builder().build();
Challenge challenge = challengeRepository.save(challenge1);
Auth auth1 = Auth.builder().challenge(challenge).build();
Auth auth2 = Auth.builder().challenge(challenge).build();
Auth auth3 = Auth.builder().challenge(challenge).build();
authRepository.save(auth1);
authRepository.save(auth2);
authRepository.save(auth3);
challengeRepository.save(challenge);
// when
Tuple auths = challengeRepository.findAuthsByChallengeId(challenge.getChallengeId());
// then
assertEquals(3, auths.size());
}
}
참조
728x90