❗Hibernate 6에서 발생한 from fetch 오류, QueryDSL로 해결
QTodo todo = QTodo.todo;
QUser user = QUser.user;
return Optional.ofNullable(
queryFactory
.select(todo)
.leftJoin(todo.user, user).fetchJoin()
.where(todo.id.eq(todoId))
.fetchOne()
);
QueryDSL을 사용해 Todo 엔티티를 User와 fetch join으로 조회하려고 했다.
Hibernate 6 환경에서 위 코드는 실행 시 JPQL 문법 오류를 발생시켰다.
fetchJoin()을 사용하는 위 코드에서 다음과 같은 JPQL을 생성했다:
select todo
from fetch todo.user as user
where todo.id = ?1
하지만 from fetch는 JPQL 문법상 허용되지 않는 구문이다.
Hibernate 6의 JPQL 파서는 더 엄격해졌기 때문에, 이렇게 잘못된 구문은 SyntaxException을 유발한다.
Caused by: java.lang.IllegalArgumentException: org.hibernate.query.SyntaxException: At 2:15 and token '.', mismatched input '.', expecting one of the following tokens: <EOF>, ',', CROSS, FULL, GROUP, INNER, JOIN, LEFT, ORDER, OUTER, RIGHT, WHERE [select todo
from fetch todo.user as user
where todo.id = ?1]
.select(todo) → .selectFrom(todo)로 변경했다.selectFrom(todo)는 내부적으로 select(todo).from(todo)를 포함하며,from 절을 명시적으로 생성해 from fetch와 같은 오류를 방지할 수 있다.return Optional.ofNullable(
queryFactory
.selectFrom(todo)
.leftJoin(todo.user, user).fetchJoin()
.where(todo.id.eq(todoId))
.fetchOne()
);
from fetch ...) 문제 해결SyntaxException) 완전 제거.selectFrom(...) 사용을 권장querydsl-jpa는 5.0.0-jakarta 이상 버전 사용 시 Hibernate 6과 호환 가능