Search in sources :

Example 1 with CustomSQLTypedQuery

use of com.blazebit.persistence.impl.query.CustomSQLTypedQuery in project blaze-persistence by Blazebit.

the class PaginatedCriteriaBuilderImpl method getIdQuery.

private TypedQuery<Object[]> getIdQuery(String idQueryString, boolean normalQueryMode, Set<JoinNode> keyRestrictedLeftJoins, List<JoinNode> entityFunctions) {
    if (normalQueryMode && isEmpty(keyRestrictedLeftJoins, ID_QUERY_CLAUSE_EXCLUSIONS)) {
        TypedQuery<Object[]> idQuery = em.createQuery(idQueryString, Object[].class);
        if (isCacheable()) {
            mainQuery.jpaProvider.setCacheable(idQuery);
        }
        if (firstResult < maximumCount && withCountQuery && withInlineCountQuery && maximumCount != Long.MAX_VALUE) {
            parameterManager.parameterizeQuery(idQuery, getDualNodeAlias());
            idQuery.setParameter(getDualNodeAlias() + "_value_0", 0L);
        } else {
            parameterManager.parameterizeQuery(idQuery);
        }
        return parameterManager.getCriteriaNameMapping() == null ? idQuery : new TypedQueryWrapper<>(idQuery, parameterManager.getCriteriaNameMapping());
    }
    TypedQuery<Object[]> baseQuery = em.createQuery(idQueryString, Object[].class);
    Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
    List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, ID_QUERY_CLAUSE_EXCLUSIONS);
    List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery, entityFunctions);
    boolean shouldRenderCteNodes = renderCteNodes(false);
    List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.EMPTY_LIST;
    QuerySpecification querySpecification = new CustomQuerySpecification(this, baseQuery, parameterManager.getParameterImpls(), parameterListNames, null, null, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), null);
    CustomSQLTypedQuery<Object[]> idQuery = new CustomSQLTypedQuery<Object[]>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), parameterManager.getValuesParameters(), parameterManager.getValuesBinders());
    if (firstResult < maximumCount && withCountQuery && withInlineCountQuery && maximumCount != Long.MAX_VALUE) {
        parameterManager.parameterizeQuery(idQuery, getDualNodeAlias());
        idQuery.setParameter(getDualNodeAlias() + "_value_0", 0L);
    } else {
        parameterManager.parameterizeQuery(idQuery);
    }
    return idQuery;
}
Also used : QuerySpecification(com.blazebit.persistence.impl.query.QuerySpecification) CustomQuerySpecification(com.blazebit.persistence.impl.query.CustomQuerySpecification) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) EntityFunctionNode(com.blazebit.persistence.impl.query.EntityFunctionNode) CustomQuerySpecification(com.blazebit.persistence.impl.query.CustomQuerySpecification) CTENode(com.blazebit.persistence.impl.query.CTENode)

Example 2 with CustomSQLTypedQuery

use of com.blazebit.persistence.impl.query.CustomSQLTypedQuery in project blaze-persistence by Blazebit.

the class AbstractCommonQueryBuilder method getTypedQuery.

protected TypedQuery<QueryResultType> getTypedQuery(StringBuilder lateralSb, JoinNode lateralJoinNode) {
    // NOTE: This must happen first because it generates implicit joins
    String baseQueryString = getBaseQueryStringWithCheck(lateralSb, lateralJoinNode);
    // We can only use the query directly if we have no ctes, entity functions or hibernate bugs
    Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
    final boolean needsSqlReplacement = isMainQuery && mainQuery.cteManager.hasCtes() || joinManager.hasEntityFunctions() || !keyRestrictedLeftJoins.isEmpty() || !isMainQuery && hasLimit();
    if (!needsSqlReplacement) {
        TypedQuery<QueryResultType> query = (TypedQuery<QueryResultType>) em.createQuery(baseQueryString, selectManager.getExpectedQueryResultType());
        if (firstResult != 0) {
            query.setFirstResult(firstResult);
        }
        if (maxResults != Integer.MAX_VALUE) {
            query.setMaxResults(maxResults);
        }
        if (isCacheable()) {
            mainQuery.jpaProvider.setCacheable(query);
        }
        parameterManager.parameterizeQuery(query);
        return applyObjectBuilder(query);
    }
    TypedQuery<QueryResultType> baseQuery = (TypedQuery<QueryResultType>) em.createQuery(baseQueryString, selectManager.getExpectedQueryResultType());
    if (isCacheable()) {
        mainQuery.jpaProvider.setCacheable(baseQuery);
    }
    Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
    String limit = null;
    String offset = null;
    // The main query will handle that separately
    if (!isMainQuery && lateralSb == null) {
        if (firstResult != 0) {
            offset = Integer.toString(firstResult);
        }
        if (maxResults != Integer.MAX_VALUE) {
            limit = Integer.toString(maxResults);
        }
    }
    List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, Collections.<ClauseType>emptySet());
    List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery);
    boolean shouldRenderCteNodes = lateralSb == null && renderCteNodes(false);
    List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.<CTENode>emptyList();
    QuerySpecification querySpecification = new CustomQuerySpecification(this, baseQuery, parameterManager.getParameterImpls(), parameterListNames, limit, offset, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), null);
    TypedQuery<QueryResultType> query = new CustomSQLTypedQuery<QueryResultType>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), parameterManager.getValuesParameters(), parameterManager.getValuesBinders());
    // The main query will use the native mechanism for limit/offset
    if (isMainQuery && lateralSb == null) {
        if (firstResult != 0) {
            query.setFirstResult(firstResult);
        }
        if (maxResults != Integer.MAX_VALUE) {
            query.setMaxResults(maxResults);
        }
    }
    parameterManager.parameterizeQuery(query);
    return applyObjectBuilder(query);
}
Also used : CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) TypedQuery(javax.persistence.TypedQuery) ObjectBuilderTypedQuery(com.blazebit.persistence.impl.query.ObjectBuilderTypedQuery) QuerySpecification(com.blazebit.persistence.impl.query.QuerySpecification) CustomQuerySpecification(com.blazebit.persistence.impl.query.CustomQuerySpecification) DefaultQuerySpecification(com.blazebit.persistence.impl.query.DefaultQuerySpecification) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) EntityFunctionNode(com.blazebit.persistence.impl.query.EntityFunctionNode) CustomQuerySpecification(com.blazebit.persistence.impl.query.CustomQuerySpecification) CTENode(com.blazebit.persistence.impl.query.CTENode)

Example 3 with CustomSQLTypedQuery

use of com.blazebit.persistence.impl.query.CustomSQLTypedQuery in project blaze-persistence by Blazebit.

the class AbstractFullQueryBuilder method getCountQuery.

protected TypedQuery<Long> getCountQuery(String countQueryString, boolean useCountWrapper) {
    // We can only use the query directly if we have no ctes, entity functions or hibernate bugs
    Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
    Set<JoinNode> alwaysIncludedNodes = getIdentifierExpressionsToUseNonRootJoinNodes();
    List<JoinNode> entityFunctions = null;
    boolean normalQueryMode = !useCountWrapper && (!isMainQuery || (!mainQuery.cteManager.hasCtes() && (entityFunctions = joinManager.getEntityFunctions(COUNT_QUERY_GROUP_BY_CLAUSE_EXCLUSIONS, true, alwaysIncludedNodes)).isEmpty() && keyRestrictedLeftJoins.isEmpty()));
    Collection<Parameter<?>> parameters;
    Map<String, String> valuesParameters;
    Map<String, ValuesParameterBinder> valuesBinders;
    JoinNode dualNode = null;
    if (cachedMaximumCount == Long.MAX_VALUE) {
        if (normalQueryMode && isEmpty(keyRestrictedLeftJoins, COUNT_QUERY_CLAUSE_EXCLUSIONS)) {
            TypedQuery<Long> countQuery = em.createQuery(countQueryString, Long.class);
            if (isCacheable()) {
                mainQuery.jpaProvider.setCacheable(countQuery);
            }
            parameterManager.parameterizeQuery(countQuery);
            return parameterManager.getCriteriaNameMapping() == null ? countQuery : new TypedQueryWrapper<>(countQuery, parameterManager.getCriteriaNameMapping());
        }
        parameters = (Collection<Parameter<?>>) (Collection<?>) parameterManager.getParameterImpls();
        valuesParameters = parameterManager.getValuesParameters();
        valuesBinders = parameterManager.getValuesBinders();
    } else {
        parameters = new ArrayList<>(parameterManager.getParameters());
        valuesParameters = new HashMap<>(parameterManager.getValuesParameters());
        valuesBinders = parameterManager.getValuesBinders();
        dualNode = createDualNode();
        entityFunctions = new ArrayList<>();
        entityFunctions.add(dualNode);
        String valueParameterName = dualNode.getAlias() + "_value_0";
        String[][] parameterNames = new String[1][1];
        parameterNames[0][0] = valueParameterName;
        ParameterManager.ValuesParameterWrapper valuesParameterWrapper = new ParameterManager.ValuesParameterWrapper(dualNode.getJavaType(), parameterNames, new AttributeAccessor[1]);
        parameters.add(new ParameterManager.ParameterImpl<Object>(dualNode.getAlias(), false, null, null, valuesParameterWrapper));
        valuesParameters.put(valueParameterName, dualNode.getAlias());
        valuesBinders.put(dualNode.getAlias(), valuesParameterWrapper.getBinder());
    }
    if (entityFunctions == null) {
        entityFunctions = joinManager.getEntityFunctions(COUNT_QUERY_GROUP_BY_CLAUSE_EXCLUSIONS, true, alwaysIncludedNodes);
    }
    Query baseQuery = em.createQuery(countQueryString);
    Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
    String limit = null;
    String offset = null;
    if (firstResult != 0) {
        offset = Integer.toString(firstResult);
    }
    if (maxResults != Integer.MAX_VALUE) {
        limit = Integer.toString(maxResults);
    }
    List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, COUNT_QUERY_CLAUSE_EXCLUSIONS);
    List<EntityFunctionNode> entityFunctionNodes;
    if (dualNode == null) {
        entityFunctionNodes = getEntityFunctionNodes(baseQuery, entityFunctions);
    } else {
        entityFunctionNodes = getEntityFunctionNodes(baseQuery, entityFunctions, Collections.<JoinNode>emptyList(), false);
    }
    boolean shouldRenderCteNodes = renderCteNodes(false);
    List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.EMPTY_LIST;
    QuerySpecification querySpecification = new CustomQuerySpecification(this, baseQuery, parameters, parameterListNames, limit, offset, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), useCountWrapper ? getCountExampleQuery() : null);
    CustomSQLTypedQuery<Long> countQuery = new CustomSQLTypedQuery<>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), valuesParameters, valuesBinders);
    if (dualNode == null) {
        parameterManager.parameterizeQuery(countQuery);
    } else {
        parameterManager.parameterizeQuery(countQuery, dualNode.getAlias());
        countQuery.setParameter(dualNode.getAlias(), Collections.singleton(0L));
    }
    return countQuery;
}
Also used : CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) Query(javax.persistence.Query) TypedQuery(javax.persistence.TypedQuery) QuerySpecification(com.blazebit.persistence.impl.query.QuerySpecification) CustomQuerySpecification(com.blazebit.persistence.impl.query.CustomQuerySpecification) EntityFunctionNode(com.blazebit.persistence.impl.query.EntityFunctionNode) CustomQuerySpecification(com.blazebit.persistence.impl.query.CustomQuerySpecification) CTENode(com.blazebit.persistence.impl.query.CTENode) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) Parameter(javax.persistence.Parameter) Collection(java.util.Collection)

Example 4 with CustomSQLTypedQuery

use of com.blazebit.persistence.impl.query.CustomSQLTypedQuery in project blaze-persistence by Blazebit.

the class BaseFinalSetOperationBuilderImpl method getTypedQuery.

@Override
@SuppressWarnings("unchecked")
protected TypedQuery<T> getTypedQuery(StringBuilder lateralSb, JoinNode lateralJoinNode) {
    if (lateralSb != null) {
        throw new IllegalStateException("Lateral join with set operations is not yet supported!");
    }
    Set<String> parameterListNames = new HashSet<String>();
    Query leftMostQuery = setOperationManager.getStartQueryBuilder().getTypedQueryForFinalOperationBuilder();
    Query baseQuery;
    parameterManager.collectParameterListNames(leftMostQuery, parameterListNames);
    Query q = leftMostQuery;
    if (leftMostQuery instanceof TypedQueryWrapper<?>) {
        q = ((TypedQueryWrapper<?>) leftMostQuery).getDelegate();
    }
    if (q instanceof AbstractCustomQuery<?>) {
        AbstractCustomQuery<?> customQuery = (AbstractCustomQuery<?>) q;
        List<Query> customQueryParticipants = customQuery.getParticipatingQueries();
        baseQuery = customQueryParticipants.get(0);
    } else {
        baseQuery = q;
    }
    List<Query> setOperands = new ArrayList<Query>();
    for (AbstractCommonQueryBuilder<?, ?, ?, ?, ?> setOperand : setOperationManager.getSetOperations()) {
        q = setOperand.getQuery();
        setOperands.add(q);
        parameterManager.collectParameterListNames(q, parameterListNames);
    }
    String limit = null;
    String offset = null;
    // Main query will get the limit applied by the native mechanism
    if (!isMainQuery) {
        if (firstResult != 0) {
            offset = Integer.toString(firstResult);
        }
        if (maxResults != Integer.MAX_VALUE) {
            limit = Integer.toString(maxResults);
        }
    }
    // Since this builder has no query of it's own, there can be no joins
    List<String> keyRestrictedLeftJoinAliases = Collections.emptyList();
    List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery);
    boolean shouldRenderCteNodes = renderCteNodes(false);
    List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(false) : Collections.EMPTY_LIST;
    QuerySpecification querySpecification = new SetOperationQuerySpecification(this, leftMostQuery, baseQuery, setOperands, setOperationManager.getOperator(), getOrderByElements(), setOperationManager.isNested(), parameterManager.getParameterImpls(), parameterListNames, limit, offset, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled());
    // Unfortunately we need this little adapter here
    @SuppressWarnings("rawtypes") TypedQuery<T> query = new CustomSQLTypedQuery<T>(querySpecification, baseQuery, parameterManager.getCriteriaNameMapping(), parameterManager.getTransformers(), parameterManager.getValuesParameters(), parameterManager.getValuesBinders());
    // The main query will use the native mechanism for limit/offset
    if (isMainQuery) {
        if (firstResult != 0) {
            query.setFirstResult(firstResult);
        }
        if (maxResults != Integer.MAX_VALUE) {
            query.setMaxResults(maxResults);
        }
    }
    parameterManager.parameterizeQuery(query);
    return applyObjectBuilder(query);
}
Also used : AbstractCustomQuery(com.blazebit.persistence.impl.query.AbstractCustomQuery) TypedQuery(javax.persistence.TypedQuery) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) Query(javax.persistence.Query) AbstractCustomQuery(com.blazebit.persistence.impl.query.AbstractCustomQuery) ArrayList(java.util.ArrayList) QuerySpecification(com.blazebit.persistence.impl.query.QuerySpecification) SetOperationQuerySpecification(com.blazebit.persistence.impl.query.SetOperationQuerySpecification) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) EntityFunctionNode(com.blazebit.persistence.impl.query.EntityFunctionNode) CTENode(com.blazebit.persistence.impl.query.CTENode) SetOperationQuerySpecification(com.blazebit.persistence.impl.query.SetOperationQuerySpecification) HashSet(java.util.HashSet) TypedQueryWrapper(com.blazebit.persistence.impl.query.TypedQueryWrapper)

Example 5 with CustomSQLTypedQuery

use of com.blazebit.persistence.impl.query.CustomSQLTypedQuery in project blaze-persistence by Blazebit.

the class Issue571Test method testBindingCteAssociationToEntityId.

@Test
// Ignore MySQL / Oracle because of unsuppored use of CTE's, ignore Hibernate 4.3 and 4.3 metamodel bug
@Category({ NoDatanucleus.class, NoEclipselink.class, NoOpenJPA.class, NoMySQLOld.class, NoOracle.class, NoHibernate42.class, NoHibernate43.class })
public void testBindingCteAssociationToEntityId() {
    expectedException.expectMessage("An association should be bound to its association type and not its identifier type");
    transactional(new TxVoidWork() {

        @Override
        public void work(EntityManager em) {
            CriteriaBuilder<MyEntity> select = cbf.create(em, MyEntity.class).withRecursive(Cte.class).from(MyEntity.class, "a").bind("myEntity").select("a.id").bind("id").select("1").unionAll().from(MyEntity.class, "a").where("a.attribute").eq("bogus").bind("myEntity").select("a.id").bind("id").select("1").end().from(Cte.class).select("myEntity");
            select.getResultList();
            String sql = ((CustomSQLTypedQuery) select.getQuery()).getQuerySpecification().getSql();
            String cteBase = sql.substring(sql.indexOf(" select") + 1, sql.lastIndexOf("UNION ALL") - 1);
            String cteRecursivePart = sql.substring(sql.indexOf("UNION ALL") + 10, sql.lastIndexOf("select") - 3);
            String queryPart = sql.substring(sql.lastIndexOf("select"));
            assertEquals("Recursive base part should project 2 columns separated by a single comma", cteBase.indexOf(","), cteBase.lastIndexOf(","));
            assertEquals("Recursive part should project 2 columns separated by a single comma", cteRecursivePart.indexOf(","), cteRecursivePart.lastIndexOf(","));
            assertEquals("Final query should project 2 columns separated by a single comma", queryPart.indexOf(","), queryPart.lastIndexOf(","));
        }
    });
}
Also used : CriteriaBuilder(com.blazebit.persistence.CriteriaBuilder) EntityManager(javax.persistence.EntityManager) TxVoidWork(com.blazebit.persistence.testsuite.tx.TxVoidWork) CustomSQLTypedQuery(com.blazebit.persistence.impl.query.CustomSQLTypedQuery) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Aggregations

CustomSQLTypedQuery (com.blazebit.persistence.impl.query.CustomSQLTypedQuery)8 CTENode (com.blazebit.persistence.impl.query.CTENode)7 EntityFunctionNode (com.blazebit.persistence.impl.query.EntityFunctionNode)7 QuerySpecification (com.blazebit.persistence.impl.query.QuerySpecification)7 CustomQuerySpecification (com.blazebit.persistence.impl.query.CustomQuerySpecification)6 TypedQuery (javax.persistence.TypedQuery)5 Collection (java.util.Collection)4 Parameter (javax.persistence.Parameter)4 ObjectBuilderTypedQuery (com.blazebit.persistence.impl.query.ObjectBuilderTypedQuery)3 TypedQueryWrapper (com.blazebit.persistence.impl.query.TypedQueryWrapper)2 Query (javax.persistence.Query)2 CriteriaBuilder (com.blazebit.persistence.CriteriaBuilder)1 AbstractCustomQuery (com.blazebit.persistence.impl.query.AbstractCustomQuery)1 DefaultQuerySpecification (com.blazebit.persistence.impl.query.DefaultQuerySpecification)1 SetOperationQuerySpecification (com.blazebit.persistence.impl.query.SetOperationQuerySpecification)1 TxVoidWork (com.blazebit.persistence.testsuite.tx.TxVoidWork)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 EntityManager (javax.persistence.EntityManager)1 Test (org.junit.Test)1