Unable to load class 'javax.persistence.Entity'.
spring data jpa 와 querydsl 을 같이 쓰는 경우 발생한 에러이다. build.gradle 파일 dependencies 에 에러 방지를 위한 아래 두 줄을 추가해주면 된다.
dependencies {
annotationProcessor "jakarta.annotation:jakarta.annotation-api" // java.lang.NoClassDefFoundError (javax.annotation.Generated) 에러 대응 코드
annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError (javax.annotation.Entity) 에러 대응 코드
}
스프링 부트의 3.0 버전으로 올라가면서 QueryDsl 패키지의 설정방법이 달라졌다고 한다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.3'
id 'io.spring.dependency-management' version '1.1.3'
}
group = 'com.ming'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.data:spring-data-rest-hal-explorer'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
///// Querydsl 설정
// 스프링 부트 3.0 미만
implementation "com.querydsl:querydsl-jpa"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" // querydsl JPAAnnotationProcessor 사용 지정
// 스프링 부트 3.0 이상
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
implementation "com.querydsl:querydsl-core"
implementation "com.querydsl:querydsl-collections"
annotationProcessor "jakarta.annotation:jakarta.annotation-api" // java.lang.NoClassDefFoundError (javax.annotation.Generated) 에러 대응 코드
annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError (javax.annotation.Entity) 에러 대응 코드
}
tasks.named('test') {
useJUnitPlatform()
}
///// 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 ]
}
///// gradle clean 시에 QClass 디렉토리 삭제
clean {
delete file(generated)
}
querydsl-jpa, querydsl-apt 라이브러리를 명시해주는 방법이 변경되었다.
querydsl 은 자동으로 Q클래스를 생성하는데 원래는 디폴트 디렉토리인 build 디렉토리에 생성이 된다.
내부적 동작 차이 때문에 인텔리제이가 빌드를 시도할 때,
Gradle 의 빌드 과정에서 스캔하는 영역과 인텔리제이가 스캔하려는 빌드 클래스 파일들이 있는 영역들을 한번 더 스캔하는 과정에서 중복 스캔이 일어난다. 첫번째 스캔에서 Q클래스 위치를 찾아서 불러왔는데 똑같은 클래스를 또 불러오는 과정에서 충돌이 일어나고 중복 에러가 발생한다.
IDEA 를 이용하여 빌드를 할 때 생길 수 있는 잠재적인 문제를 해결하기 위해서 Q클래스의 위치를 강제로 꺼내오는 옵션을 추가적으로 설정해주었다.
querydsl 이 추가가 잘 되었고
querydsl 이 만들어주는 Q클래스이다.