Search in sources :

Example 1 with CollectionInsertModificationQuerySpecification

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

the class AbstractInsertCollectionCriteriaBuilder method getQuerySpecification.

private <R> QuerySpecification getQuerySpecification(Query baseQuery, Query exampleQuery, String[] returningColumns, ReturningObjectBuilder<R> objectBuilder, Map<DbmsModificationState, String> includedModificationStates) {
    Set<String> parameterListNames = parameterManager.getParameterListNames(baseQuery);
    Set<JoinNode> keyRestrictedLeftJoins = getKeyRestrictedLeftJoins();
    List<String> keyRestrictedLeftJoinAliases = getKeyRestrictedLeftJoinAliases(baseQuery, keyRestrictedLeftJoins, Collections.EMPTY_SET);
    List<EntityFunctionNode> entityFunctionNodes = getEntityFunctionNodes(baseQuery);
    boolean isEmbedded = this instanceof ReturningBuilder;
    boolean shouldRenderCteNodes = renderCteNodes(isEmbedded);
    List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(isEmbedded) : Collections.EMPTY_LIST;
    ExtendedQuerySupport extendedQuerySupport = getService(ExtendedQuerySupport.class);
    Query insertExampleQuery = getInsertExampleQuery();
    String insertExampleSql = extendedQuerySupport.getSql(em, insertExampleQuery);
    String ownerAlias = extendedQuerySupport.getSqlAlias(em, insertExampleQuery, entityAlias);
    String targetAlias = extendedQuerySupport.getSqlAlias(em, insertExampleQuery, JoinManager.COLLECTION_DML_BASE_QUERY_ALIAS);
    JoinTable joinTable = mainQuery.jpaProvider.getJoinTable(entityType, collectionName);
    int joinTableIndex = SqlUtils.indexOfTableName(insertExampleSql, joinTable.getTableName());
    String collectionAlias = SqlUtils.extractAlias(insertExampleSql, joinTableIndex + joinTable.getTableName().length());
    String[] selectItemExpressions = SqlUtils.getSelectItemExpressions(insertExampleSql, SqlUtils.indexOfSelect(insertExampleSql));
    // Prepare a Map<EntityAlias.idColumnName, CollectionAlias.idColumnName>
    // This is used to replace references to id columns properly in the final sql query
    Map<String, String> columnExpressionRemappings = new HashMap<>(selectItemExpressions.length);
    String[] discriminatorColumnCheck = mainQuery.jpaProvider.getDiscriminatorColumnCheck(entityType);
    if (discriminatorColumnCheck != null) {
        columnExpressionRemappings.put(ownerAlias + "." + discriminatorColumnCheck[0] + "=" + discriminatorColumnCheck[1], "1=1");
    }
    if (joinTable.getKeyColumnMappings() != null) {
        for (Map.Entry<String, String> entry : joinTable.getKeyColumnMappings().entrySet()) {
            columnExpressionRemappings.put(collectionAlias + "." + entry.getValue(), entry.getKey());
        }
    }
    for (Map.Entry<String, String> entry : joinTable.getIdColumnMappings().entrySet()) {
        columnExpressionRemappings.put(ownerAlias + "." + entry.getValue(), entry.getKey());
    }
    for (Map.Entry<String, String> entry : joinTable.getTargetColumnMappings().entrySet()) {
        columnExpressionRemappings.put(targetAlias + "." + entry.getValue(), entry.getKey());
    }
    int cutoffColumns = 0;
    StringBuilder insertSqlSb = new StringBuilder();
    insertSqlSb.append("insert into ").append(joinTable.getTableName()).append("(");
    for (String selectItemExpression : selectItemExpressions) {
        String columnExpression = columnExpressionRemappings.get(selectItemExpression.trim());
        // It should never be null, but the workaround for https://hibernate.atlassian.net/browse/HHH-13045 requires us to filter out the entity fetch columns
        if (columnExpression == null) {
            cutoffColumns++;
        } else {
            insertSqlSb.append(columnExpression).append(',');
        }
    }
    insertSqlSb.setCharAt(insertSqlSb.length() - 1, ')');
    return new CollectionInsertModificationQuerySpecification(this, baseQuery, exampleQuery, parameterManager.getParameterImpls(), parameterListNames, keyRestrictedLeftJoinAliases, entityFunctionNodes, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, isEmbedded, returningColumns, objectBuilder, includedModificationStates, returningAttributeBindingMap, getInsertExecutorQuery(), insertSqlSb.toString(), cutoffColumns, getForeignKeyParticipatingQueries(), mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled());
}
Also used : ReturningBuilder(com.blazebit.persistence.ReturningBuilder) TypedQuery(javax.persistence.TypedQuery) CustomSQLQuery(com.blazebit.persistence.impl.query.CustomSQLQuery) Query(javax.persistence.Query) CustomReturningSQLTypedQuery(com.blazebit.persistence.impl.query.CustomReturningSQLTypedQuery) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CollectionInsertModificationQuerySpecification(com.blazebit.persistence.impl.query.CollectionInsertModificationQuerySpecification) ExtendedQuerySupport(com.blazebit.persistence.spi.ExtendedQuerySupport) EntityFunctionNode(com.blazebit.persistence.impl.query.EntityFunctionNode) CTENode(com.blazebit.persistence.impl.query.CTENode) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) JoinTable(com.blazebit.persistence.spi.JoinTable)

Aggregations

ReturningBuilder (com.blazebit.persistence.ReturningBuilder)1 CTENode (com.blazebit.persistence.impl.query.CTENode)1 CollectionInsertModificationQuerySpecification (com.blazebit.persistence.impl.query.CollectionInsertModificationQuerySpecification)1 CustomReturningSQLTypedQuery (com.blazebit.persistence.impl.query.CustomReturningSQLTypedQuery)1 CustomSQLQuery (com.blazebit.persistence.impl.query.CustomSQLQuery)1 EntityFunctionNode (com.blazebit.persistence.impl.query.EntityFunctionNode)1 ExtendedQuerySupport (com.blazebit.persistence.spi.ExtendedQuerySupport)1 JoinTable (com.blazebit.persistence.spi.JoinTable)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 Query (javax.persistence.Query)1 TypedQuery (javax.persistence.TypedQuery)1