현재 프로젝트는 jdbc로 sql 쿼리가 엄청 복잡하게 흩날리고 있다.
프로젝트를 맡은지 이제 한달 정도 됐고 새로 복잡한 검색 기능을 구현해야하는데 동적 쿼리 사용이 편리하고 디버깅도 수월하고 코드로 쿼리를 작성하여 가독성도 좋은 Querydsl을 적용하고자 했다.
사실 지난번에 한번 시도했다가 에러를 해결하면서 계속 할 시간이 없어서 포기하고 criteria를 사용해서 구현을 했었는데 이번에는 꼭 해내겠다는 마음으로 도전해봤다. 싱겁게 해결됐는데 엄청 고생 했다.
적용할 프로젝트 버전
Spring 2.1.4
gradle 5.2.1
Java 8
jsp
프로젝트에 Querydsl 설정을 추가
dependencies {
...
compile("com.querydsl:querydsl-jpa")
annotationProcessor("com.querydsl:querydsl-apt")
}
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
library = "com.querydsl:querydsl-apt"
jpa = true
querydslSourcesDir = querydslDir
}
compileQuerydsl{
options.annotationProcessorPath = configurations.querydsl
}
configurations {
querydsl.extendsFrom compileClasspath
}
sourceSets {
main {
java {
srcDirs = ['src/main/java', querydslDir]
}
}
}
build도 잘 되고 코드 작성하고 api 호출도 잘 됐다.
그리고 이제 페이지에 접속해 테스트하려고 했더니 갑자기 에러가 발생
에러 1
org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: [22] in the generated java file: Syntax error, parameterized types are only available if source level is 1.5 or greater
어쩌고 에러가 발생하여 검색했더니 jsp와 querydsl이 충돌하여 발생한다고 나왔다.
버전을 명시하지 않고 querydsl 의존성을 추가 했을 때 4.1.x 버전이 자동으로 추가됐다.
챗지피티에게 물어보니 springboot 2.1.x 버전에서는 4.2.1 버전을 사용하면 된다고 하여 일단 build.gradle에 버전 명시
그래도 해결되지 않음
검색을 통해 org.eclipse.jdt.core.compiler:ecj 이 패키지로 인한 오류로 exclude 해주면 된다고 함
그래서 build.gradle을 수정했다.
implementation group: 'com.querydsl', name: 'querydsl-apt', version: '4.2.1'
// Exclude org.eclipse.jdt.core.compiler:ecj from the dependency
implementation(group: 'com.querydsl', name: 'querydsl-apt', version: '4.2.1') {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
그래도 해결되지 않음
에러 2
이것저것 시도하다가 갑자기 빌드할 때 Unable to load class 'javax.persistence.Entity'. 에러가 발생
이거는 apt를 추가할 때 뒤에 :jpa를 붙였었는데 제거했더니 해결됐다.
어쨌든 jsp가 계속 에러가 났다. api 호출은 잘 되는데 jsp만 오류가 나서 페이지에 접속이 불가능
querydsl 최신 버전에서는 해결된 문제라는 댓글을 언뜻 보고 querydsl 버전을 5.0.0으로 수정해보았다.
// querydsl
implementation "com.querydsl:querydsl-jpa:5.0.0"
implementation "com.querydsl:querydsl-apt:5.0.0"
그랬더니 jsp가 잘 동작하고 페이지에 접속할 수 있었다.
버전 에러가 날까봐 부랴부랴 repository를 생성해서 api에 연결하고 테스트했더니 또 에러가 발생했다.
에러 발생 3
Could not initialize class com.querydsl.jpa.impl.JPAProvider
패키지를 확인해보니 querydsl-core 패키지만 4버전대라서 core도 5.0.0버전으로 추가 명시해줬다.
implementation "com.querydsl:querydsl-core:5.0.0"
다시 빌드하고 테스트를 해보니 잘 동작했다.
해결!
최종 querydsl 관련 build.gradle 설정
plugins {
id 'org.springframework.boot' version '2.1.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
...
}
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.ewerk.gradle.plugins.querydsl'
...
sourceCompatibility = '1.8'
ext {
...
queryDslVersion = '5.0.0'
}
dependencies {
...
// querydsl
implementation "com.querydsl:querydsl-jpa:${queryDslVersion}"
implementation "com.querydsl:querydsl-apt:${queryDslVersion}"
implementation "com.querydsl:querydsl-core:${queryDslVersion}"
}
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
library = "com.querydsl:querydsl-apt"
jpa = true
querydslSourcesDir = querydslDir
}
compileQuerydsl{
options.annotationProcessorPath = configurations.querydsl
}
configurations {
querydsl.extendsFrom compileClasspath
}
sourceSets {
main {
java {
srcDirs = ['src/main/java', querydslDir]
}
}
}
...
참고
'개발 > Spring' 카테고리의 다른 글
| [SpringBoot] MySQL 연결 에러 (0) | 2023.09.06 |
|---|---|
| [SpringBoot] 이메일 전송(텍스트, html) (0) | 2023.09.04 |
| [Querydsl] 서브쿼리 사용하기 (0) | 2023.07.03 |
| [JPA] flush(), clear() (0) | 2023.03.28 |
| [JPA] API 조회 기능 개발 정리 (0) | 2023.03.28 |