private QueryPlanWork specificationToWork(Specification<T> spec, Pageable pageable) { // Unwrap to Hibernate final QueryImpl query = getQuery(spec, pageable).unwrap(QueryImpl.class); final String hql = query.getQueryString(); // Create translator final QueryTranslator queryTranslator = new ASTQueryTranslatorFactory().createQueryTranslator("", hql, Collections.emptyMap(), em.unwrap(SessionImplementor.class).getFactory(), null); queryTranslator.compile(Collections.emptyMap(), false); // Get translated query and parameters final String sql = queryTranslator.getSQLString(); final Object[] parameters = translateParameters(query, queryTranslator); // Done return new QueryPlanWork(sql, parameters); }
/** * Do not use in production code! Only for testing purposes only. Used for example during query engine upgrade. * Method provides translation from hibernate HQL query to plain SQL string query. * * @param sessionFactory * @param hqlQueryText * @return SQL string, null if hqlQueryText parameter is empty. */ public static String toSql(SessionFactory sessionFactory, String hqlQueryText) { Validate.notNull(sessionFactory, "Session factory must not be null."); if (StringUtils.isEmpty(hqlQueryText)) { return null; } final QueryTranslatorFactory translatorFactory = new ASTQueryTranslatorFactory(); final SessionFactoryImplementor factory = (SessionFactoryImplementor) sessionFactory; final QueryTranslator translator = translatorFactory. createQueryTranslator( hqlQueryText, hqlQueryText, Collections.EMPTY_MAP, factory, null ); translator.compile(Collections.EMPTY_MAP, false); return translator.getSQLString(); }
@Override protected TypedQuery<Long> getCountQuery(final Specification<T> spec) { final CriteriaBuilder builder = em.getCriteriaBuilder(); final CriteriaQuery<T> criteria = builder.createQuery(getDomainClass()); final Root<T> root = applySpecificationToQueryCriteria(spec, criteria); criteria.select(root); final TypedQuery<T> query = em.createQuery(criteria); final AbstractQueryImpl hibernateQuery = query.unwrap(AbstractQueryImpl.class); @SuppressWarnings("unchecked") final Map<String, TypedValue> pNamedParameters = (Map<String, TypedValue>) getField(hibernateQuery, AbstractQueryImpl.class, "namedParameters"); final String hql = hibernateQuery.getQueryString(); final ASTQueryTranslatorFactory queryTranslatorFactory = new ASTQueryTranslatorFactory(); final SessionImplementor hibernateSession = em.unwrap(SessionImplementor.class); final QueryTranslator queryTranslator = queryTranslatorFactory.createQueryTranslator("", hql, Collections.emptyMap(), hibernateSession.getFactory(), null); queryTranslator.compile(Collections.emptyMap(), false); final String sql = queryTranslator.getSQLString(); final ParameterTranslations paramTranslations = queryTranslator.getParameterTranslations(); final String countSql = String.format("select count(*) from (%s limit %d) as sqry", sql, maximumRecords + 1); final Query nativeQuery = em.createNativeQuery(countSql); final AbstractQueryImpl resultQuery = nativeQuery.unwrap(AbstractQueryImpl.class); if (pNamedParameters != null) { for (final Entry<String, TypedValue> entry : pNamedParameters.entrySet()) { for (final int index : paramTranslations.getNamedParameterSqlLocations(entry.getKey())) { resultQuery.setParameter(index, entry.getValue().getValue(), entry.getValue().getType()); } } } return new CustomCountQueryWrapper(nativeQuery); }