queryMixin.addProjection(args);
return createQuery(false);
}
private Query createQuery(boolean forCount) {
NativeSQLSerializer serializer = (NativeSQLSerializer) serialize(forCount);
String queryString = serializer.toString();
logQuery(queryString);
List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection();
Query query;
Expression<?> proj = projection.get(0);
if (!FactoryExpression.class.isAssignableFrom(proj.getClass()) && isEntityExpression(proj)) {
if (projection.size() == 1) {
if (queryHandler.createNativeQueryTyped()) {
query = entityManager.createNativeQuery(queryString, proj.getType());
} else {
query = entityManager.createNativeQuery(queryString);
}
} else {
throw new IllegalArgumentException("Only single element entity projections are supported");
}
} else {
query = entityManager.createNativeQuery(queryString);
}
if (!forCount) {
ListMultimap<Expression<?>, String> aliases = serializer.getAliases();
Set<String> used = Sets.newHashSet();
if (proj instanceof FactoryExpression) {
for (Expression<?> expr : ((FactoryExpression<?>)proj).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(proj)) {
queryHandler.addEntity(query, extractEntityExpression(proj).toString(), proj.getType());
} else if (aliases.containsKey(proj)) {
for (String scalar : aliases.get(proj)) {
if (!used.contains(scalar)) {
queryHandler.addScalar(query, scalar, proj.getType());
used.add(scalar);
break;
}
}
}
}
if (lockMode != null) {
query.setLockMode(lockMode);
}
if (flushMode != null) {
query.setFlushMode(flushMode);
}
for (Map.Entry<String, Object> entry : hints.entries()) {
query.setHint(entry.getKey(), entry.getValue());
}
// set constants
JPAUtil.setConstants(query, serializer.getConstantToLabel(), queryMixin.getMetadata().getParams());
FactoryExpression<?> wrapped = projection.size() > 1 ? FactoryExpressionUtils.wrap(projection) : null;
if ((projection.size() == 1 && projection.get(0) instanceof FactoryExpression) || wrapped != null) {
Expression<?> expr = wrapped != null ? wrapped : projection.get(0);