Search in sources :

Example 1 with CollectionDeleteModificationQuerySpecification

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

the class AbstractDeleteCollectionCriteriaBuilder 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);
    boolean isEmbedded = this instanceof ReturningBuilder;
    boolean shouldRenderCteNodes = renderCteNodes(isEmbedded);
    List<CTENode> ctes = shouldRenderCteNodes ? getCteNodes(isEmbedded) : Collections.EMPTY_LIST;
    // Prepare a Map<EntityAlias.idColumnName, CollectionAlias.idColumnName>
    // This is used to replace references to id columns properly in the final sql query
    ExtendedQuerySupport extendedQuerySupport = getService(ExtendedQuerySupport.class);
    String sql = extendedQuerySupport.getSql(em, baseQuery);
    String ownerAlias = extendedQuerySupport.getSqlAlias(em, baseQuery, entityAlias);
    String targetAlias = extendedQuerySupport.getSqlAlias(em, baseQuery, JoinManager.COLLECTION_DML_BASE_QUERY_ALIAS);
    JoinTable joinTable = collectionAttribute.getJoinTable();
    if (joinTable == null) {
        throw new IllegalStateException("Deleting inverse collections is not supported!");
    }
    int joinTableIndex = SqlUtils.indexOfTableName(sql, joinTable.getTableName());
    String collectionAlias = SqlUtils.extractAlias(sql, joinTableIndex + joinTable.getTableName().length());
    String tableToDelete = joinTable.getTableName();
    String tablePrefix = mainQuery.dbmsDialect.getDeleteJoinStyle() == DeleteJoinStyle.FROM ? collectionAlias : tableToDelete;
    Map<String, String> columnExpressionRemappings = new HashMap<>(joinTable.getIdColumnMappings().size());
    List<String> joinTableIdColumns = new ArrayList<>();
    if (joinTable.getKeyColumnMappings() != null) {
        for (Map.Entry<String, String> entry : joinTable.getKeyColumnMappings().entrySet()) {
            joinTableIdColumns.add(entry.getKey());
            columnExpressionRemappings.put(CollectionDmlSupportFunction.FUNCTION_NAME + "(" + collectionAlias + "." + entry.getValue() + ")", tablePrefix + "." + entry.getKey());
        }
    }
    String[] discriminatorColumnCheck = mainQuery.jpaProvider.getDiscriminatorColumnCheck(entityType);
    if (discriminatorColumnCheck != null) {
        columnExpressionRemappings.put(ownerAlias + "." + discriminatorColumnCheck[0] + "=" + discriminatorColumnCheck[1], "1=1");
    }
    for (Map.Entry<String, String> entry : joinTable.getIdColumnMappings().entrySet()) {
        joinTableIdColumns.add(entry.getKey());
        columnExpressionRemappings.put(CollectionDmlSupportFunction.FUNCTION_NAME + "(" + ownerAlias + "." + entry.getValue() + ")", tablePrefix + "." + entry.getKey());
    }
    for (Map.Entry<String, String> entry : joinTable.getTargetColumnMappings().entrySet()) {
        columnExpressionRemappings.put(CollectionDmlSupportFunction.FUNCTION_NAME + "(" + targetAlias + "." + entry.getValue() + ")", tablePrefix + "." + entry.getKey());
    }
    // If the id attribute is an embedded type, there is the possibility that row value expressions are used which we need to handle as well
    Set<SingularAttribute<?, ?>> idAttributes = JpaMetamodelUtils.getIdAttributes(entityType);
    if (idAttributes.size() == 1 && idAttributes.iterator().next().getType() instanceof ManagedType<?>) {
        StringBuilder leftSb = new StringBuilder();
        StringBuilder rightSb = new StringBuilder();
        leftSb.append(CollectionDmlSupportFunction.FUNCTION_NAME).append("((");
        rightSb.append("(");
        for (Map.Entry<String, String> entry : joinTable.getIdColumnMappings().entrySet()) {
            leftSb.append(ownerAlias).append('.').append(entry.getValue()).append(", ");
            rightSb.append(tablePrefix).append('.').append(entry.getKey()).append(',');
        }
        leftSb.setLength(leftSb.length() - 2);
        leftSb.append("))");
        rightSb.setCharAt(rightSb.length() - 1, ')');
        columnExpressionRemappings.put(leftSb.toString(), rightSb.toString());
    }
    return new CollectionDeleteModificationQuerySpecification(this, baseQuery, exampleQuery, parameterManager.getParameterImpls(), parameterListNames, mainQuery.cteManager.isRecursive(), ctes, shouldRenderCteNodes, isEmbedded, returningColumns, objectBuilder, includedModificationStates, returningAttributeBindingMap, mainQuery.getQueryConfiguration().isQueryPlanCacheEnabled(), tableToDelete, collectionAlias, joinTableIdColumns.toArray(new String[0]), false, getDeleteExampleQuery(), columnExpressionRemappings);
}
Also used : ReturningBuilder(com.blazebit.persistence.ReturningBuilder) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CollectionDeleteModificationQuerySpecification(com.blazebit.persistence.impl.query.CollectionDeleteModificationQuerySpecification) SingularAttribute(javax.persistence.metamodel.SingularAttribute) ExtendedQuerySupport(com.blazebit.persistence.spi.ExtendedQuerySupport) CTENode(com.blazebit.persistence.impl.query.CTENode) HashMap(java.util.HashMap) 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 CollectionDeleteModificationQuerySpecification (com.blazebit.persistence.impl.query.CollectionDeleteModificationQuerySpecification)1 ExtendedQuerySupport (com.blazebit.persistence.spi.ExtendedQuerySupport)1 JoinTable (com.blazebit.persistence.spi.JoinTable)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 SingularAttribute (javax.persistence.metamodel.SingularAttribute)1