private Query createQuery(boolean forCount) {
        NativeSQLSerializer serializer = (NativeSQLSerializer) serialize(forCount);
        String queryString = serializer.toString();
        logQuery(queryString);
        Expression<?> projection = queryMixin.getMetadata().getProjection();
        Query query;

        if (!FactoryExpression.class.isAssignableFrom(projection.getClass()) && isEntityExpression(projection)) {
            if (queryHandler.createNativeQueryTyped()) {
                query = entityManager.createNativeQuery(queryString, projection.getType());
            } else {
                query = entityManager.createNativeQuery(queryString);
            }

        } else {
            query = entityManager.createNativeQuery(queryString);
        }
        if (!forCount) {
            Map<Expression<?>, List<String>> aliases = serializer.getAliases();
            Set<String> used = new HashSet<>();
            if (projection instanceof FactoryExpression) {
                for (Expression<?> expr : ((FactoryExpression<?>) projection).getArgs()) {
                    if (isEntityExpression(expr)) {
                        queryHandler.addEntity(query, extractEntityExpression(expr).toString(), expr.getType());
                    } else if (aliases.containsKey(expr)) {
                        for (String scalar : aliases.get(expr)) {
                            if (!used.contains(scalar)) {
                                queryHandler.addScalar(query, scalar, expr.getType());
                                used.add(scalar);
                                break;
                            }

                        }
                    }
                }
            } else if (isEntityExpression(projection)) {
                queryHandler.addEntity(query, extractEntityExpression(projection).toString(), projection.getType());
            } else if (aliases.containsKey(projection)) {
                for (String scalar : aliases.get(projection)) {
                    if (!used.contains(scalar)) {
                        queryHandler.addScalar(query, scalar, projection.getType());
                        used.add(scalar);
                        break;
                    }
                }
            }
        }

        if (lockMode != null) {
            query.setLockMode(lockMode);
        }
        if (flushMode != null) {
            query.setFlushMode(flushMode);
        }

        for (Map.Entry<String, Object> entry : hints.entrySet()) {
            query.setHint(entry.getKey(), entry.getValue());
        }


        // set constants
        JPAUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams());
        this.projection = null; // necessary when query is reused

        if (!forCount && projection instanceof FactoryExpression) {
            if (!queryHandler.transform(query, (FactoryExpression<?>) projection)) {
                this.projection = (FactoryExpression<?>) projection;
            }
        }

        return query;
    }
{@code AbstractJPASQLQuery} is the base class for JPA Native SQL queries

@param <T> result type
@param <Q> concrete subtype

@author tiwe*
querydsl-jpa/src/main/java/com/querydsl/jpa/sql/AbstractJPASQLQuery.java