QueryDSL에서 추상 클래스 Entity 사용하기

hoyong.eom·2025년 5월 10일

JPA

목록 보기
7/8
post-thumbnail

QueryDSL에서 추상클래스 Entity 처리하기

오늘은 토이프로젝트를 진행하던 과정에서 발생했던 오류와 간단한 해결 방법에 대해서 정리하고자 합니다.

문제 상황은 다음과 같습니다.

  • 추상클래스로 선언된 Card JPA Entity
  • Card Entity를 상속받은 BusArricalCard
  • Card Entity를 상속받은 SubwayArrivalCard
  • Card JPA Entity에는 공통된 속성이 존재
    ex) cardId, cardName, user, cardGroup

문제가 발생된 케이스는 다음과 같습니다.

QueryDSL에서 공통된 속성을 조회할때는 QCard를 사용하고, 그렇지 않은 경우에는 QSubwayArricalCard, QBusArrivalCard를 사용하면 되지 않을까?

결론 부터 이야기하자면 에러입니다.

에러 발생 코드는 다음과 같습니다.

queryFactory
    .selectFrom(busArrivalCard)
    .join(busArrivalCard.cardGroup, cardGroup)
    .join(busArrivalCard.user, user).fetchJoin()
    .where(
        userIdEq(add.getUserId()),
        cardNameEq(add.getCardName()),
        cardGroupIdEq(add.getCardGroupId()),
        busStopIdEq(add.getBusStopId()),
        busStopNameEq(add.getBusStopName()),
        busStopCityCodeEq(add.getCityCode())
    )
    .fetchOne();                                
private BooleanExpression cardGroupIdEq(Long cardGroupId) {
    return cardGroupId == null ? null : card.cardGroup.id.eq(cardGroupId);
}

private BooleanExpression userIdEq(String userId) {
    return hasLength(userId)
        ? card.user.userId.eq(userId)
        : null;
}

private BooleanExpression cardNameEq(String cardName) {
    return hasLength(cardName)
        ? card.cardName.eq(cardName)
        : null;
}

문제가 발생했던 부분은 selectFrom에서 지정한 Entitywhere에서 지정된 Entity가 다르기 때문에 문제가 발생했습니다.

에러는 다음과 같습니다.

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.query.SemanticException: Could not interpret path expression 'card.user.userId'
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:371) ~[spring-orm-6.1.14.jar:6.1.14]
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246) ~[spring-orm-6.1.14.jar:6.1.14]

결론

BusArrivalCardSubwayArrivalCardCard를 상속받기 때문에 공통된 속성인 cardId, cardName, User와 같은 정보를 조회할때는 QCard를 사용해도 된다고 생각했으나, selectFromWhere 코드는 같은 Q객체를 사용해야합니다

0개의 댓글