Copy Joins of criteriaQuery to countQuery setting isFetched as false

In below method, restrictions coming with join and fetch lists. I want to create countQuery where i want to copy the joins and fetch statements, and make join with fetch as false in my count query.

'public Integer getTotalCount(com.sfnt.ems.dao.common.Restrictions<T> restrictions) {
	CriteriaBuilder builder = getSession().getCriteriaBuilder();
	CriteriaQuery<T> criteriaQuery=restrictions.getCriteriaQuery();
	Predicate finalPredicate=criteriaQuery.getRestriction();
	Set<Root<?>> roots = criteriaQuery.getRoots();
    Root<?> root = roots.iterator().next();
	SqmSelectStatement countQuery = (SqmSelectStatement) builder.createQuery(Long.class);
	Root<T> rootCountQuery = countQuery.from(getPersistentClass());
	countQuery.select(root);
	
	SqmSubQuery sqmSubQuery = (SqmSubQuery<Tuple>) countQuery.subquery(Tuple.class);
	SqmSelectStatement sqmOriginalQuery = (SqmSelectStatement) criteriaQuery;
	SqmQuerySpec sqmOriginalQuerySpec = sqmOriginalQuery.getQuerySpec();
	sqmOriginalQuerySpec.setSortSpecifications(Collections.emptyList());
	countQuery.setQueryPart(sqmOriginalQuerySpec.copy(SqmCopyContext.simpleContext()));

	countQuery.select(builder.count(builder.literal(1)));
	Query query =  getSession().createQuery(countQuery);
	Long count = (Long) HQLQuery.getUniqueResult(query);
	return count.intValue();
}'

Kindly help. Exception facing is SemanticException: query specified join fetching, but the owner of the fetched association was not present in the select list.

As a solution I am trying to iterate the list of joins and set isFetched as false somehow.
'AbstractSqmFrom rootSelection = (AbstractSqmFrom)criteriaQuery.getSelection();
List selectionJoins= rootSelection.getSqmJoins();
for(SqmJoin j:selectionJoins) {
System.out.println(j.getSqmJoinType()));
} ’
List here giving me normal joins and fetch-join both.

You can’t just use random From/Root objects in a query. These objects are bound to the query through which they were created. This topic was discussed multiple times already. Use the search feature: java.lang.IllegalArgumentException: Already registered a copy: SqmBasicValuedSimplePath

Many thanks for the reply Beikov. I have used countQuery.setQueryPart(sqmOriginalQuerySpec.copy(SqmCopyContext.simpleContext()));
sqmNode#copy, right?

But still facing the same exception: SemanticException: query specified join fetching, but the owner of the fetched association was not present in the select list.

My code works completely fine if having joins but if i am using fetch also in my restrictions, the code breaks with above mentioned exception.

Here when i run my select records query, selection.getSelectableNode value is my entityClass name And hence my selectedFromSet contains the value.
But for my count query, selection.getSelectableNode value is count function which result in empty value in selectedFromSet collection.

And hence for my fetched join, it goes to assertFetchOwner function with empty value in selectedFromSet and having entity class name in owner variable resulting into above exception.

We are using predicates of select query in our count query with above code.

Possible solution I am thinking is for my count function:

  1. If i am able to convert fetch join to normal join.
  2. If we can pass count and entity class name as selection.getSelectableNode so it can fill the selectedFromSet collection for fetch join.

Kindly suggest/direct us to the correct path here.

In that case, you can’t just copy the query. You will have to rebuild it but without join fetches.