Skip to content

count query fails to be auto generated when using @Query annotation with fetch join #2348

Closed
@sinbom

Description

@sinbom

findAllFetch method causes the following error. however, findAllNotFetch method does not cause errors.
because the automatically generated countQuery does not include the fetch keyword. likewise, fetch join paging using @entitygraph does not cause an error.

public interface BoardRepository extends JpaRepository<Board, Long> {

    @Query(value = "SELECT DISTINCT b FROM Board b LEFT JOIN FETCH b.comments ORDER BY b.id")
    Page<Board> findAllFetch(Pageable pageable);
    
    @Query(value = "SELECT DISTINCT b FROM Board b LEFT JOIN b.comments ORDER BY b.id")
    Page<Board> findAllNotFetch(Pageable pageable);

    @EntityGraph(attributePaths = "comments")
    Page<Board> findAll(Pageable pageable);

}
Caused by: org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list [FromElement{explicit,not a collection join,fetch join,fetch non-lazy properties,classAlias=null,role=com.example.demo.entity.Board.comments,tableName=comment,tableAlias=comments1_,origin=board board0_,columns={board0_.id,className=com.example.demo.entity.Comment}}]
	at org.hibernate.hql.internal.ast.tree.SelectClause.initializeExplicitSelectClause(SelectClause.java:215) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.ast.HqlSqlWalker.useSelectClause(HqlSqlWalker.java:1028) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:796) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:694) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:330) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:278) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
	... 125 common frames omitted

whether it is fetch join or not does not affect count query results. what is important is the association of the fetching entity.
of course, I know that the count query generated in the findAllNotFetch method has inaccurate paging. but, paging would have been accurate if it was not a collection fetch.

i wonder, the QueryUtils class removes unnecessary queries that do not affect results such as order by, but why the fetch does not. Is this intentional?

public static String createCountQueryFor(String originalQuery, @Nullable String countProjection) {

		Assert.hasText(originalQuery, "OriginalQuery must not be null or empty!");

		Matcher matcher = COUNT_MATCH.matcher(originalQuery);
		String countQuery;

		if (countProjection == null) {

			String variable = matcher.matches() ? matcher.group(VARIABLE_NAME_GROUP_INDEX) : null;
			boolean useVariable = StringUtils.hasText(variable) //
					&& !variable.startsWith(" new") //
					&& !variable.startsWith("count(") //
					&& !variable.contains(","); //

			String complexCountValue = matcher.matches() && StringUtils.hasText(matcher.group(COMPLEX_COUNT_FIRST_INDEX))
					? COMPLEX_COUNT_VALUE
					: COMPLEX_COUNT_LAST_VALUE;

			String replacement = useVariable ? SIMPLE_COUNT_VALUE : complexCountValue;
			countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, replacement));
		} else {
			countQuery = matcher.replaceFirst(String.format(COUNT_REPLACEMENT_TEMPLATE, countProjection));
		}

		return countQuery.replaceFirst(ORDER_BY_PART, "");
	}

Metadata

Metadata

Assignees

Labels

in: query-parserEverything related to parsing JPQL or SQLtype: bugA general bug

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions