티스토리 뷰

보통 JPA를 활용하여 개발할 때 데이터베이스에 Y, N 여부 값을 넣을 경우에는 boolean converter를 따로 만들어서 사용하곤 한다.

하지만, 경우에 따라 버그(?)가 발생하는 경우가 있어 남긴다.

 

CONFIG 테이블에 BooleanToYNConverter를 사용하는 칼럼이 있어, DB값이 Y라면 엔티티에는 true, 반대의 경우에는 false로 가져올 때,  해당 칼럼을 where 절로 쿼리를 select 할 때, case when 구문으로 true, false를 임의로 주면 파라미터 바인딩이 제대로 되지 않는 현상이다.

 

샘플 코드는 아래를 보자.

@Entity
@Table(name = "CONFIG")
@Setter
public class Config {

    @Id
    @GeneratedValue
    @Column(name = "Config_Seq")
    private Long configSeq;

    @Column(name = "User_Seq")
    private Long userSeq;

    @Column(name = "Apply_Date")
    private LocalDate applyDate;

    @Convert(converter = BooleanToYNConverter.class)
    @Column(name = "Use_Yn")
    private Boolean useYn;

}

Config엔티티는 위와 같이 구성되어있고, useYn 필드가 BooleanToYNConverter 컨버트를 사용하게 된다.

 

@Converter
public class BooleanToYNConverter implements AttributeConverter<Boolean, String> {

    @Override
    public String convertToDatabaseColumn(Boolean attribute) {
        return attribute != null && attribute ? "Y" : "N";
    }

    @Override
    public Boolean convertToEntityAttribute(String s) {
        return "Y".equalsIgnoreCase(s);
    }
}

컨버트는 무난하게 많이 사용하는 형태로 이상 없이 작성되어 있다.

 

query
	.selectFrom(config)
	.where(config.useYn.eq(true))
	.fetch();

이때, 위와 같은 쿼리를 querydsl로 날리면, 아래와 같이 Use_Yn =  'Y'로 컨버트 되어 쿼리가 실행되게 된다.

 

지금까지는 정상적인 동작이다.

그럼 이제  select절에  case when을 써보자.

조건문에 파라미터가 true로 들어가는 현상이 나타난다.

혹시라도 로깅에만 그렇게 찍히는 건지 useYn을 false로 바꿔보자.

조건문을 바꿔 실행해보면 컨버터가 잘 실행된 상태로 N 값으로 쿼리가 나간다. 

내가 처음 이 문제를 보았을 때, 완전 갈피를 못 잡았었다.

true일 때만 발생하는 현상으로, querydsl부터 실제 쿼리가 나갈 때 까지 디버깅을 태워본 결과 컨버터가 적용 안된다 라고만 알 수 있었고, 정확히 어떤 원인인지는 파악하지 못했다.(아직 부족한 게 많다.)

 

암튼.. 어떻게든 이 문제를 해결하기 위해 별에 별짓을 다해본 결과, case builder에서 true로 결과를 가져올 때, 발생하는 현상이었다.

아무 설정 바꾸지 않은 채로, case builder에서 true만 false로 바꾸었더니 정상적으로 파라미터가 컨버터가 적용되어 Y값으로 바인딩되어 쿼리가 실행되는 것을 확인할 수 있다.

 

이와 관련하여  querydsl에 이슈를 남겨보았으나 기존에도 있던 이슈로 답변이 왔다. JPQL의 문제다 라고 말하는 것처럼 보이는데, 확인하라고 알려준 이슈내용이 어떤 건지 모르겠어서 정확히 파악이 안 되었다 ㅠㅠ

* 이슈 : https://github.com/querydsl/querydsl/issues/3017

 

Querydsl parameter binding problem with @Convert Field · Issue #3017 · querydsl/querydsl

Observed vs. expected behavior When the field to which @convert is applied is used as a search condition, if true is returned to the casebuilder statement in select, the @convert is not applied to ...

github.com

 

 

 querydsl도 결국 JPQL을 기반으로 동작한다고 알고 있지만.. 이런 경우에도 JPQL의 영향인건지는 잘 이해가지 않는다..

 

내가 테스트한 환경은 4.2.1버전이였다.

특이한 건 4.3.0~ 4.4.0 버전까지는 같은 코드로 아예 쿼리 자체가 실행되지 않는 오류가 뜨고, 가장 최신 버전은 5.0.0 버전에서는 컨버터가 정상적으로 적용되고 있는 것으로 확인된다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함