• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

JPQL 동적쿼리 부분 - > QUERYDSL 마이그레이션 후 질문

23.09.03 16:59 작성 조회수 309

0

querydsl설정은 각종 블로그 보고 설정 적용을 한상태입니다.

 

일단 엔티티 구조가

Transaction 엔티티에서

Accout 엔티티를 @MantToOne 다대일 단방향 매핑중이고,

입출금 내역 조회부분에서 jpql 부분을 그대로 챗 gpt 에 querydsl 기준 동적쿼리 코드를 돌려보면

이런 코드를 알려줍니다 우선 여기서

질문이

  1. WithdrawAccount, DepositAccount라는 클래스는 없고 Account를 참조 하는데 QWithdrawAccount, QDepositAccount Q클래스가 필요한 이유를 모르겠습니다.

저 코드를

해당 코드와 같이 바꿨습니다 그리고 테스트 코드를 돌려보면

 

transaction.withdrawAccount is not a root path 라는 에러가 나는데

root path 관련 질문글 찾아보면

" 이를 해결하려면 from 절에서 해당 객체를 다시 선언해주면 됩니다. 즉, querydsl에서는 join을 할 때 alias를 줘서 해당 객체를 다시 선언해주는 방식으로 작성해야 해결할 수 있습니다. "
이런 답변이있는데

변경 된 코드에서 innerjoin의 오른쪽 파라미터에 별칭을 잘못 줘서 에러가 나는거 같긴 한데

QTransaction.transaction.withdrawaccount 와 같은 별칭을 부여하면 안되는 걸까요,,?

답변 2

·

답변을 작성해보세요.

0

ykmykm4608님의 프로필

ykmykm4608

질문자

2023.09.11

혹시 fetchjoin 적용 안된거 같은데 할필요가 없는걸까요?

 

  public List<Transaction> findTransactionList(Long accountId, String gubun, Integer page){

            JPAQuery<Transaction> query = jpaQueryFactory.selectFrom(transaction);

        return  query
                     .leftJoin(transaction.withdrawAccount).leftJoin(transaction.depositAccount)
                     .where(gubunCheck(gubun, accountId))
                     .limit(3).offset(page*3)
                     .fetch();

    }
    
    private BooleanExpression gubunCheck(String gubun, Long accountId){
        if (!StringUtils.hasText(gubun)){
            return
                    transaction.withdrawAccount.id.eq(accountId).or(transaction.depositAccount.id.eq(accountId));

        }else if(TransactionEnum.valueOf(gubun) == TransactionEnum.DEPOSIT){
            return
                    fetchjtransaction.depositAccount.id.eq((accountId));
        }else if(TransactionEnum.valueOf(gubun) == TransactionEnum.WITHDRAW){
            return
                    transaction.withdrawAccount.id.eq(accountId);
        }else {
            return null;
        }
    }
ykmykm4608님의 프로필

ykmykm4608

질문자

2023.09.11


@Override
public List<Transaction> findTransactionList(Long accountId, String gubun, Integer page) {

    JPAQuery<Transaction> query = jpaQueryFactory.selectFrom(transaction);

    if ("WITHDRAW".equals(gubun)) {
            query
                .innerJoin(transaction.withdrawAccount, QAccount.account)
                .fetchJoin()
                .where(transaction.withdrawAccount.id.eq(accountId));
    } else if ("DEPOSIT".equals(gubun)) {
             query
                 .innerJoin(transaction.depositAccount, QAccount.account)
                 .fetchJoin()
                 .where(transaction.depositAccount.id.eq(accountId));
    } else { // gubun = alls
            query
                .leftJoin(transaction.withdrawAccount, QAccount.account)
                .leftJoin(transaction.depositAccount, QAccount.account)
                .where(transaction.withdrawAccount.id.eq(accountId)
                        .or(transaction.depositAccount.id.eq(accountId)));
    }

    return query
            .offset(page * 5)
            .limit(5)
            .fetch();
}

혹시 booleanexpression을 써야하나요?? 그리고 보여주신 링크는 좀 쿼리 자체가 달라서 jpql 쿼리부터,,

0

ykmykm4608님의 프로필

ykmykm4608

질문자

2023.09.03

 

이렇게 하니 되네요,,? QAccout Q클래스가 맞았나 봅니다..,,

QAccount withdrawAccount = QAccount.account;
QAccount depositAccount = QAccount.account;

https://github.com/codingspecialist/JUNIT5-Security-Lecture/commit/04563b7813f8c8e51c7da4f05649f760f9079526

쿼리 DSL 적용된 커밋 로그입니다.

 

git clone 받아서

git reset --hard 0456

 

하면 코드 확인가능합니다.