Hibernate 5 CriteriaBuilder关联查询报错修复:获取最新版本Content数据
First, let's break down why your current code is throwing that error. The generated HQL shows the subquery is missing a FROM clause and incorrectly reusing the parent query's alias for both sides of the equality check. This happens because you used subquery.correlate(root)—this method links the subquery to the parent's root alias instead of creating a separate alias for the subquery, which is critical to replicate your original SQL logic (comparing c1.id to c2.id where c2 is a separate instance of the Content table).
Here's the corrected implementation that matches your intended SQL query:
CriteriaBuilder criteriaBuilder = currentSession().getCriteriaBuilder(); CriteriaQuery<Content> parentQuery = criteriaBuilder.createQuery(Content.class); Root<Content> root = parentQuery.from(Content.class); // Parent query selects the root Content entity parentQuery.select(root); // Create subquery to fetch the max version for each id Subquery<Integer> subquery = parentQuery.subquery(Integer.class); Root<Content> subRoot = subquery.from(Content.class); // Create a separate root for the subquery subquery.select(criteriaBuilder.max(subRoot.get(Content_.contentPK).get(ContentPK_.version))); // Link the subquery's id to the parent query's id subquery.where(criteriaBuilder.equal( subRoot.get(Content_.contentPK).get(ContentPK_.id), root.get(Content_.contentPK).get(ContentPK_.id) )); // Parent query filter: match the current row's version to the max version from the subquery parentQuery.where(criteriaBuilder.equal( root.get(Content_.contentPK).get(ContentPK_.version), subquery )); return currentSession().createQuery(parentQuery).list();
Key Fixes Explained:
- Replaced
subquery.correlate(root)withsubquery.from(Content.class): This creates a distinct alias (likec2in your original SQL) for the subquery, allowing you to compare the parent'sidto the subquery'sidcorrectly. - Proper
FROMclause in the subquery: This resolves the "from where" syntax error in the generated HQL. - Correct equality check: The subquery now compares
c2.id = c1.idas intended, ensuring we get the maximum version for each uniqueid.
This corrected code will generate HQL equivalent to your target SQL query, returning only the latest version of each Content entity grouped by id.
内容的提问来源于stack exchange,提问作者igopimac13

