QueryDsl Bulider
BooleanExpression의 한계?
QueryDsl 쿼리 조건(where)를 예전에 다수의 BooleanExpression 메소드를 구성해서 잘 구동하였다고 생각하였으나 웹페이지에서 페이지 번호를 클릭하여 다른 페이지로 이동할 때 결국 500 에러가 출력되었다.
에러가 일어난 원인은 저번에 검색 기능을 BooleanExpression으로 조건을 구성할 때 처음 서버를 구동하여 검색 키워드와 카테고리의 값은 당연히 없으니 null 값들이 들어가기에 nullpointerexception에러가 출력되었다.
그래서 키워드와 카테고리 둘 다 null인 경우를 조건으로 넣어 게시판 웹페이지 첫번째 페이지는 정상적으로 나왔기에 해결했다고 생각했으나 이번에 이런저런 코드들을 추가하면서 다음 페이지를 넘어갈려고 하니 발견하게 된 에러인데 다음페이지를 넘어가면 새롭게 서버에서는 검색 메소드가 실행되면서 url에 반환되는 키워드와 카테고리 값은 null이기에 에러가 발생한 것 같다.
- 에러가 출력된 null 에러 로그
- url 주소에 키워드(keyword)와 카테고리(type)의 값이 없는 상태
BooleanBuilder와 병행
저번에 BooleanExpression를 사용했을 때 null이 들어가면 무시가 되지 않고 nullpointerexception에러가 일어나는 경우 때문에 해결하는데 골치가 아팠는데 결국 비슷한 경우가 또 발생하니 또 BooleanExpression으로 로직을 어떻게든 비트는 것은 어려워 보였다.
그래서 이번에는 BooleanBuilder를 단일 메소드를 생성하여 그 메소드 안에 기존의 BooleanExpression 메소드들을 추가하는 방법을 사용하기로 하였다.
BooleanBuilder를 다시 사용한 이유는 전에 사용했을 때는 이러한 nullpointerexception에러가 나타나지 않았기에 QueryDsl의 where 조건문에 첫번째로 BooleanBuilder를 넣으면 정상적으로 null를 무시하지 않을까 싶어 시도해보기로 하였다. 코드는 아래와 같이 구성하였다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Override
public Page<BoardListAllDTO> searchWithAll(String[] types, String keyword, Pageable pageable){
JPQLQuery<Board> query = from(board)
.where(board.bno.gt(0L)
.and(allCond(types,keyword)))
.leftJoin(reply).on(reply.board.eq(board)).groupBy(board);
getQuerydsl().applyPagination(pageable, query);
....
private BooleanBuilder allCond(String[] types, String keyword) {
BooleanBuilder builder = new BooleanBuilder();
if((types != null && types.length > 0) && keyword != null ){
return builder
.or(CheckTitle(types,keyword))
.or(CheckContent(types,keyword))
.or(CheckUser(types,keyword));
}
return null;
}
private BooleanExpression CheckTitle(String[] types, String keyword){
return Arrays.asList(types).contains("t") == true ? board.title.contains(keyword) : null;
}
private BooleanExpression CheckContent(String[] types, String keyword){
return Arrays.asList(types).contains("c") == true ? board.content.contains(keyword) : null;
}
private BooleanExpression CheckUser(String[] types, String keyword){
return Arrays.asList(types).contains("u") == true ? board.user.contains(keyword) : null;
}
느낀 점
위와 같은 코드로 수정한 후 다시 서버를 구동시켜 웹페이지를 다른 페이지로 이동을 시도한 결과 정상적으로 다른 페이지들이 출력되었다.
그래서 이번에 느낀 점은 애초에 BooleanExpression으로 바꾼 이유가 BooleanBuilder를 사용할 때에 단일 조건을 구성할 때에는 괜찮겠지만 조건들이 많아지면 이러한 코드양이 길어지기 때문에 복잡하기에 BooleanExpression으로 조건들을 메소드로 생성하여 관리하기 편하다는 것이었다.
하지만 어느 기술이든 장점만 있는 것이 아니었기에 이러한 편리함 때문에 특정 기술에 함몰되선 안되며 어느 정도 이번 해결한 것처럼 병행하거나 경우에 따라 선택할 수 있는 판단을 갖춰야 할 것 같다.