Project/Newsfeed

[프로젝트] QueryDSL 사용 시 Q클래스 import 불가 문제 해결 (gradle)

쉬지마 이굥진 2024. 3. 2. 19:57

[✏️ 문제]

프로젝트 중, QueryDSL을 사용해서 뉴스피드 검색 기능을 구현하는 과정에서,  

RepositoryImpl 클래스에서 Q클래스 import가 안되는 문제가 발생했다. 

 

툴을 이용한 자동 임포트가 안 돼서, 강제로 입력 해도 안 됐다 ..(당연히)

import가 안 됐던 Qclass

 

[✏️ 분석]

build.gradle에 설정을 잘못했나 해서 dependencies도 다시 들여다 보고,  Configuration 클래스 관련 문제인가 싶어 다시 점검해 보아도 잘못 설정한 것은 없었다.

그러다 문득 import가 안된다면 경로 문제인 것이 아닐까 싶어 Q클래스가 속해 있는 루트 파일을 봤다. 

Querydsl 사용 시, 자동 생성되는 Q 클래스 파일들은 보통build/generated 디렉토리에 있다.

 

문제 상황 발생 당시에 Q클래스 파일은 정상적으로 build/generated 디렉토리 밑에 정상적으로 있었는데, 인텔리제이가 이 Q클래스 파일들을 인식 못하는 문제로 보였다.

 

쿼리 DSL을 사용하기 위해 구글링하며 build.gradle에 플러그인과 dependencies들을 추가해 주었는데, 스프링 부트의 버전이 3.0으로 올라가면서 QueryDSL의 설정 방법이 달라진 것을 모르고 2.* 버전의 설정 방법을 쓴 것도 영향이 있었던 것 같다. 

 

[✏️ 해결 시도]

(저와 같은 문제로 고민하고 계신 분들은 아래 사항 모두 시도 해보시기를 추천합니다)

 

1.  build 방식 바꾸기

구글링 결과 빌드 방법을 바꾸고 해결하신 분들도 보여서 gradle 이었던 빌드 방식을 →  IntelliJ IDEA 빌드로 바꿔서 다시 재시작 해보았는데도 import는 되지 않았다.

 

2.  캐시 삭제 및 프로젝트 클린하기 (invalidate Caches/Project Clean)

스프링 3 버전에 맞게 plugin과 dependencies들을 수정했는데도 되지 않아,

기존 빌드가 남아있어서 빌드가 안 되나 싶어 캐시를 삭제해 봤는데도 import는 되지 않았다. 

File > Invalidate Caches > 원하는 범위만큼 체크 > 무효화 및 다시 시작 클릭

 

3. ⭕(필자가 성공한 방법) Q클래스 파일의 자동 생성 위치 build.gradle에서 지정하기

 

[✏️ 해결]

프로젝트를 클린했는데도 IDE에서 build/generated 디렉토리를 인식하지 못해,

인식하게 하는 방법을 찾다가 Q클래스 파일 자동 생성 위치를 지정해주는 방법을 찾았다.

다음과 같은 설정들을 build.gradle 파일에 추가했다.

 

1.  generated 변수에 src/main/generated 디렉토리로 Q클래스의 생성 위치를 저장

2.  gradle의 JavaCompile 작업을 수행할 때, Q클래스를 생성할 위치를 generated 변수를 통해 지정
3.
 
sourceSets에서 기존의 소스 코드 경로에 추가로 Q클래스가 생성되는 경로를 추가 :

이는 Java 컴파일러가 소스 코드를 찾아갈 경로를 지정해주는 것.

4.  clean 작업을 수행 시, Q클래스가 생성되는 디렉토리를 삭제하도록 설정 :

이렇게 하면 프로젝트를 클린할 때마다 Q 클래스 파일들도 함께 삭제되어, 새로운 Q 클래스 파일들이 정상적으로 생성될 수 있도록 함.

 

간단히 말하면 :

이 설정은 Q 클래스를 'src/main/generated' 디렉토리에 생성하고, Java 컴파일러가 이 디렉토리를 참조하도록 설정하며, 빌드를 청소할 때 이 디렉토리를 삭제하도록 설정하고 있는 것!  이렇게 함으로써 Q 클래스의 생성과 관리를 자동화할 수 있다.

지정한 위치에 Q클래스가 생성됨을 확인!

 

프로젝트를 재빌드 하니, 정상적으로 Q클래스가 import 됨을 확인할 수 있었다.  :-)

 

[📌 주의 할 점]

다만, 이렇게 설정했을 땐 src 밑에 생성된 파일들이기 때문에 git에 push했을 때 이런 Q클래스들도 함께 깃허브에 올라가게 된다.

Q클래스들은 QueryDSL 라이브러리를 사용하면서 자동으로 생성되는 파일들이다. 이렇게 자동으로 생성되는 파일들을 Git과 같은 버전 관리 시스템에 포함시키는 것은 일반적으로 .. 피해야 한다.

 

(번외) 피해야 하는 이유들 :

  1. 코드 불필요성 :
    Q 클래스들은 개발자가 직접 작성한 코드가 아니라, 특정 라이브러리에 의해 자동 생성된 코드다. 이런 코드들은 프로젝트의 원본 소스 코드와는 별개로 관리되어야 하고, 이를 Git에 포함시키면 원본 소스 코드와 자동 생성 코드가 섞여서 코드 관리가 어려워진다.
  2. 빌드 과정 중복 :
    Q 클래스들은 빌드 과정 중에 자동으로 생성된다. 따라서 이 파일들을 Git에 포함시키면, 다른 개발자가 소스 코드를 받아서 빌드할 때 불필요하게 중복된 빌드 과정을 거치게 된다.
    또한 Q 클래스 파일이 이미 존재하고 변경되지 않은 상태에서 빌드를 시도하면, 빌드 도구가 이전에 생성된 Q 클래스 파일과 새로 생성하려는 Q 클래스 파일이 서로 다르다고 판단하여 오류를 발생시킬 수 있다. 이런 오류는 빌드 과정을 복잡하게 만들고, 빌드를 실패시키는 원인이 된다.
  3. 변경 추적 불필요 :
    Q 클래스들은 개발자가 직접 변경하는 코드가 아니라, 소스 코드의 변경에 따라 자동으로 변경되는 코드다. 따라서 이 코드의 변경 사항을 Git을 통해 추적하는 것은 불필요하다고 할 수 있다.

그러니 gitignore 에 추가해 주자!

### Qclass ###
/src/main/generated/

 


[✏️ 평가 및 회고]

개발자 환경에 따라서 QueryDSL 설정 방법이 천차 만별인 것 같다. . 내가 설정한 방법이 어떤 분에겐 안될 수도 있고 어떤 분에겐 될 수도 있다. (심지어 나와 똑같은 코드인데 mac에선 인식이 됐던 억울한 (?) 상황도 있었음)

그래도 이런 에러가 나서 QueryDSL 설정과 build 로직에 대해 이해했기 때문에 앞으로 관련 에러가 나도 잘 해결할 수 있을 것 같다.

다시 되돌아보면 이 에러로 인해 반나절 동안 삽질은 했지만, 그냥 동작이 됐다면 몰랐을 것들도 알게 돼서 나름 성장한 것 같아 기분이 좋다. 

그리고 처음 쓰는 기능이 있다면, 구글링을 하더라도 나의 build 방식과 버전 등등을 따져 본 후 적용해야겠다고 생각했다.