org.hibernate.sql.ast.SqlTreeCreationException: Could not locate TableGroup

Hi,

We are migrating from 5.6 to 6.4.4. We are getting org.hibernate.sql.ast.SqlTreeCreationException: Could not locate TableGroup while executing the below criteria query

@Entity
public class NbaTraining {
    private Long id;
    private NbaPof nbaPof;
    private Blob trainingData;
    private Date inserted;
    private Date updated;
// getter and setters
} 

@Entity
public class NbaPof implements Comparable {
    private Long id;
    private String representationTitle;
    private String representationGuid;
    private Blob pofJson;
    private Date inserted;
    private Date updated;
//getter ad setter
}

@Repository
@Transactional
public class MyDaoClass {
       .........

       CriteriaBuilder criteriaBuilder = sessionFactory.getCurrentSession().getCriteriaBuilder();
        CriteriaQuery<NbaTraining> nbaTrainingQuery =
                criteriaBuilder.createQuery(NbaTraining.class);
        Root<NbaTraining> nbaTrainingQueryRoot = nbaTrainingQuery.from(NbaTraining.class);
        nbaTrainingQuery.select(nbaTrainingQueryRoot);

        Subquery<NbaPof> nbaPofSubQuery = nbaTrainingQuery.subquery(NbaPof.class);

        Subquery<NbaPof> nbaPofMaxUpdatedSubQuery = nbaPofSubQuery.subquery(NbaPof.class);
        Root<NbaPof> nbaPofMaxUpdatedSubQueryRoot = nbaPofMaxUpdatedSubQuery.from(NbaPof.class);
        Predicate titleEqual = criteriaBuilder
                .equal(nbaPofMaxUpdatedSubQueryRoot.get("representationTitle"), nbaPofTitle);
        Predicate guidEqual = criteriaBuilder
                .equal(nbaPofMaxUpdatedSubQueryRoot.get("representationGuid"), nbaPofGuid);
        // greatest requires this Expression cast for hibernate enhance while compiling
        nbaPofMaxUpdatedSubQuery
                .select(criteriaBuilder
                        .greatest((Expression) nbaPofMaxUpdatedSubQueryRoot.get("updated")))
                .where(titleEqual, guidEqual);


        Root<NbaPof> nbaPofSubQueryRoot = nbaPofSubQuery.from(NbaPof.class);
        nbaPofSubQuery.select(nbaPofSubQueryRoot.get("id")).where(
                criteriaBuilder.equal(nbaPofSubQueryRoot.get("updated"), nbaPofMaxUpdatedSubQueryRoot.get("updated")));

        nbaTrainingQuery
                .where(nbaTrainingQueryRoot.join("nbaPof").get("id").in(nbaPofSubQueryRoot.get("id")));

        nbaTrainingQuery.orderBy(criteriaBuilder.desc(nbaTrainingQueryRoot.get("updated")));

        List<NbaTraining> nbaTrainings = sessionFactory.getCurrentSession()
                .createQuery(nbaTrainingQuery).setFirstResult(0).setMaxResults(1).list();
        .........
}

This code worked fine with 5.6. Not getting any clue on what could be the problem. Any help is appreciated.

Full stacktrace below

error details: org.hibernate.sql.ast.SqlTreeCreationException: Could not locate TableGroup - com.motive.wf.pof.NbaPof(122482762361300)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.prepareReusablePath(BaseSqmToSqlAstConverter.java:3676)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.prepareReusablePath(BaseSqmToSqlAstConverter.java:3622)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.prepareReusablePath(BaseSqmToSqlAstConverter.java:3607)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitBasicValuedPath(BaseSqmToSqlAstConverter.java:4269)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitBasicValuedPath(BaseSqmToSqlAstConverter.java:440)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath.accept(SqmBasicValuedSimplePath.java:145)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitInListPredicate(BaseSqmToSqlAstConverter.java:7839)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitInListPredicate(BaseSqmToSqlAstConverter.java:440)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.tree.predicate.SqmInListPredicate.accept(SqmInListPredicate.java:147)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitWhereClause(BaseSqmToSqlAstConverter.java:2484)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:2061)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:440)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.tree.select.SqmQuerySpec.accept(SqmQuerySpec.java:127)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.spi.BaseSemanticQueryWalker.visitQueryPart(BaseSemanticQueryWalker.java:218)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQueryPart(BaseSqmToSqlAstConverter.java:1915)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:1600)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:440)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.tree.select.SqmSelectStatement.accept(SqmSelectStatement.java:228)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.translate(BaseSqmToSqlAstConverter.java:776)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:402)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:327)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:303)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:509)
	at deployment.SMPEAR-JBoss-240.0.0.5-SNAPSHOT.ear//org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:427)

This query worked by accident in ORM 5. It’s simply not well formed. You are trying to refer to Root objects in the context of a query, that was defined for a subquery.

Here is the correct code.

public class MyDaoClass {
       .........

       CriteriaBuilder criteriaBuilder = sessionFactory.getCurrentSession().getCriteriaBuilder();
        CriteriaQuery<NbaTraining> nbaTrainingQuery =
                criteriaBuilder.createQuery(NbaTraining.class);
        Root<NbaTraining> nbaTrainingQueryRoot = nbaTrainingQuery.from(NbaTraining.class);
        nbaTrainingQuery.select(nbaTrainingQueryRoot);

        Subquery<Long> nbaPofSubQuery = nbaTrainingQuery.subquery(Long.class);

        Subquery<Date> nbaPofMaxUpdatedSubQuery = nbaPofSubQuery.subquery(Date.class);
        Root<NbaPof> nbaPofMaxUpdatedSubQueryRoot = nbaPofMaxUpdatedSubQuery.from(NbaPof.class);
        Predicate titleEqual = criteriaBuilder
                .equal(nbaPofMaxUpdatedSubQueryRoot.get("representationTitle"), nbaPofTitle);
        Predicate guidEqual = criteriaBuilder
                .equal(nbaPofMaxUpdatedSubQueryRoot.get("representationGuid"), nbaPofGuid);
        // greatest requires this Expression cast for hibernate enhance while compiling
        nbaPofMaxUpdatedSubQuery
                .select(criteriaBuilder
                        .greatest((Expression) nbaPofMaxUpdatedSubQueryRoot.get("updated")))
                .where(titleEqual, guidEqual);


        Root<NbaPof> nbaPofSubQueryRoot = nbaPofSubQuery.from(NbaPof.class);
        nbaPofSubQuery.select(nbaPofSubQueryRoot.get("id")).where(
                criteriaBuilder.equal(nbaPofSubQueryRoot.get("updated"), nbaPofMaxUpdatedSubQuery));

        nbaTrainingQuery
                .where(nbaTrainingQueryRoot.join("nbaPof").get("id").in(nbaPofSubQuery));

        nbaTrainingQuery.orderBy(criteriaBuilder.desc(nbaTrainingQueryRoot.get("updated")));

        List<NbaTraining> nbaTrainings = sessionFactory.getCurrentSession()
                .createQuery(nbaTrainingQuery).setFirstResult(0).setMaxResults(1).list();
        .........
}

Thanks a lot @beikov . This worked !!