Querydsl을 사용하기 위해서는 다소 번거로운 Gradle 설정 및 사용법 등을 익혀야한다.
Q클래스가 import 자체가 안돼서 생성이 안되는 오류 해결 방법들을 정리해두려고 한다. Q클래스 import 오류는 보통 Querydsl 설정 문제로 인해 발생한다.
IDE: IntelliJ, Build Tool: Gradle 사용
Querydsl 5.0 이상에서는 Java 17 이상을 권장한다.
터미널에서 명령어로 프로젝트의 Java 버전 확인해보기.
java -version
만약 Java 8, 11이라면 17 이상으로 변경 후 다시 빌드해보자.
사용 중인 IDE(IntelliJ, Eclipse 등)에서 annotation processing 기능이 활성화되어 있는지 확인해보자
File - Settings - Build, Execution, Deployment - Compiler - Annotation Processors
"Enable annotation processing" 옵션 체크
File - Settings - Build, Execution, Deployment - Build Tools - Gradle
"Build and run using" 을 Gradle 로 설정
Q클래스가 생성되었는데도 import가 안 된다면, IntelliJ에서 소스 폴더로 인식되지 않았을 수 있다.
File - Project Structure - Modules - Sources 탭 이동
좌측의 폴더 트리에서 Q클래스 생성 경로로 지정한(ex: src/main/generated) 폴더가 파란색으로 표시되는지 확인한다. 만약 폴더가 일반 폴더(회색)로 표시된다면 해당 폴더를 오른쪽 커서로 클릭 후 "Sources" 버튼을 클릭해서 소스 폴더로 지정한다.
Apply 후 File - Invalidate Caches/Restart 옵션을 사용해 캐시를 정리하고 재빌드를 해보자.
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
implementation "com.querydsl:querydsl-core"
implementation "com.querydsl:querydsl-collections"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" // querydsl JPAAnnotationProcessor 사용 지정
annotationProcessor "jakarta.annotation:jakarta.annotation-api" // java.lang.NoClassDefFoundError (javax.annotation.Generated) 에러 대응 코드
annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError (javax.annotation.Entity) 에러 대응 코드
dependencyManagement.importedProperties['querydsl.version'] 값이 올바르게 설정되어 있는지 확인해볼까?
터미널에서 이 명령어를 실행하면 querydsl 관련 의존성 버전을 확인할 수 있다.
./gradlew dependencyInsight --dependency querydsl-apt
이 명령어는 실제로 어떤 버전이 적용되고 있는지 상세하게 보여준다.
터미널 출력 결과 일부를 캡쳐해왔다. 보면 com.querydsl:querydsl-apt의 버전은 5.0.0으로 올바르게 사용되고 있는 것이 맞다.
Querydsl이 Q클래스를 생성하려면, annotation processor가 정상적으로 동작해야 한다.
build.gradle 파일에서 생성 디렉토리를
// Querydsl 설정부
def generated = 'src/main/generated'
// querydsl QClass 파일 생성 위치를 지정
tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(generated))
}
// java source set 에 querydsl QClass 위치 추가
sourceSets {
main.java.srcDirs += [ generated ]
}
로 지정했으므로 Q 클래스는 src/main/generated 폴더에 생성되어야 한다.
현재 build.gradle에서 Querydsl JPA 의존성은
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
로 jakarta 버전을 사용하고 있지만,
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa"
는 jakarta 버전이 아니라 javax 버전을 참조할 수 있다.
Querydsl APT 의존성도 jakarta 버전으로 일치시켜야 한다.
이렇게 하면 APT가 jakarta.persistence.Entity를 참조하게 되어 NoClassDefFoundError 문제가 해결될 가능성이 높다.
즉, 모든 Querydsl 관련 의존성이 동일하게 jakarta 버전을 사용하도록 일관되게 맞춰주면 문제 해결에 도움이 된다.
main 함수가 있는 <프로젝트명>Application 클래스에
@SpringBootApplication(scanBasePackages = "com.ming.projectboard")
를 추가하는 것을 권장한다. 이는 Spring Boot가 해당 패키지 하위의 모든 컴포넌트와 엔티티를 제대로 스캔하게 도와준다.
터미널에서 아래 명령어로 Gradle 빌드 수행
./gradlew clean compileJava
또는 ./gradlew clean build
생성된 파일 확인해보기.
빌드 후 프로젝트 디렉토리에서 src/main/generated 폴더를 열어보고 Q<엔티티명>.java 파일이 정상적으로 생성되었는지 확인해본다.
캐시 문제를 배제하기 위해 클린 빌드도 해보기
./gradlew clean compileJava --refresh-dependencies
Q클래스가 생성되지 않는 주요 원인은 Querydsl이 엔티티를 인식하지 못하는 경우일 것이다.
Querydsl 설정이 잘못되었는지 다시 확인해보기.
@Entity 를 선언한 JPA 엔티티 클래스가 없는건 아닌지, @Entity가 올바르게 선언은 되어 있는지 확인해보기.