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());
}
Aggregations