Unit test failing for CriteriaQuery with Count with Hibernate 6.4.2

With Hibernate 6.4.2 we are using createCountQuery() from existing CriteriaQuery and count returned is expected.

Usage:

private Long getArtifactsCount(final CriteriaQuery<Artifact> artifactCriteriaQuery) {
    final CriteriaQuery<Long> countQuery = ((SqmSelectStatement<Artifact>) artifactCriteriaQuery).createCountQuery();
    return this.entityManager.createQuery(countQuery).getSingleResult();
}

Our Scenario:

We are computing our artifactCriteriaQuery.getResultList() using the CriteriaQuery<Artifact> and the count query on this artifactCriteriaQuery requires this type casted
((SqmSelectStatement<Artifact>) artifactCriteriaQuery).createCountQuery();

Issue:
Unit test fails as we are unable to mock the type casted object
((SqmSelectStatement<Artifact>) artifactCriteriaQuery).createCountQuery();

Because it is now requires both CriteriaQuery<Artifact> and SqmSelectStatement<Artifact> for the same mocked object.

Error Stack:

java.lang.ClassCastException: class jakarta.persistence.criteria.CriteriaQuery$MockitoMock$mG0O5D8O cannot be cast to class org.hibernate.query.sqm.tree.select.SqmSelectStatement (jakarta.persistence.criteria.CriteriaQuery$MockitoMock$mG0O5D8O and org.hibernate.query.sqm.tree.select.SqmSelectStatement are in unnamed module of loader 'app')

Is there a proper way to be able to unit test this scenario?

I don’t know how you are mocking, but can’t you just create a mock for the SqmSelectStatement type?

Thanks for the reply @beikov .

Let me explain the scenario a little better.

Previously:

when(this.artifactCriteriaQuery.select(any())).thenReturn(this.artifactCriteriaQuery);
when(this.artifactCriteriaQuery.where(any(Expression.class))).thenReturn(this.artifactCriteriaQuery);
when(this.artifactCriteriaQuery.from(Artifact.class)).thenReturn(this.artifactRoot);
when(this.artifactCriteriaQuery.subquery(Package.class)).thenReturn(this.getLibraryPackageIdFromPackage);

it now changed to:

when(this.artifactCriteriaQuery.select(any())).thenReturn(this.sqmSelectStatementMock);
when(this.artifactCriteriaQuery.where(any(Expression.class))).thenReturn(this.sqmSelectStatementMock);
when(this.sqmSelectStatementMock.from(Artifact.class)).thenReturn(mock(SqmRoot.class));
when(this.sqmSelectStatementMock.subquery(Package.class)).thenReturn(mock(SqmSubQuery.class));
when(this.sqmSelectStatementMock.createCountQuery()).thenReturn(mock(JpaCriteriaQuery.class));

Now the issue is that, even before reaching the countQuery itself it fails because it is now not able to resolve the artifactRoot

How can we resolve this?

Try to step back and think about what you’re doing here. Why do you want to mock the query building facility of Hibernate ORM? This makes no sense to me. Just let Hibernate build the query.