Search in sources :

Example 1 with CorrelationMultisetTupleElementMapper

use of com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper in project blaze-persistence by Blazebit.

the class ViewTypeObjectBuilderTemplate method applyCorrelatedSubviewMapping.

@SuppressWarnings("unchecked")
private ViewTypeObjectBuilderTemplate<Object[]>[] applyCorrelatedSubviewMapping(AbstractAttribute<?, ?> attribute, String attributePath, TupleIdDescriptor tupleIdDescriptor, ManagedViewTypeImplementor<Object[]> managedViewType, TupleElementMapperBuilder mapperBuilder, Set<Feature> features, ViewJpqlMacro viewJpqlMacro, EmbeddingViewJpqlMacro embeddingViewJpqlMacro, ExpressionFactory ef, int batchSize, boolean dirtyTracking) {
    Expression correlationResult = attribute.getCorrelationResultExpression();
    String correlationBasis = attribute.getCorrelationBasis();
    CorrelationProviderFactory factory = attribute.getCorrelationProviderFactory();
    String correlationAlias = CorrelationProviderHelper.getDefaultCorrelationAlias(attributePath);
    if (attribute.getFetchStrategy() == FetchStrategy.JOIN || attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
        @SuppressWarnings("unchecked") String subviewAliasPrefix = mapperBuilder.getAlias(attribute, false);
        correlationBasis = mapperBuilder.getMapping(attribute.getCorrelationBasisExpression());
        Limiter limiter = createLimiter(mapperBuilder, correlationAlias, attribute);
        String correlationExternalAlias;
        if (limiter == null) {
            correlationExternalAlias = correlationAlias;
        } else {
            correlationExternalAlias = CorrelationProviderHelper.getDefaultExternalCorrelationAlias(attributePath);
        }
        String subviewIdPrefix = correlationExternalAlias;
        if (!ExpressionUtils.isEmptyOrThis(correlationResult)) {
            subviewIdPrefix = PrefixingQueryGenerator.prefix(ef, correlationResult, correlationExternalAlias, viewRoot.getEntityViewRootTypes().keySet(), true);
        }
        String subviewMappingPrefix = subviewIdPrefix;
        int startIndex;
        if (attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
            startIndex = 0;
        } else {
            startIndex = tupleOffset + mapperBuilder.mapperIndex();
        }
        boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
        TupleIdDescriptor subviewTupleIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
        TupleIdDescriptor subviewIdDescriptor;
        if (managedViewType instanceof ViewType<?>) {
            // When the attribute is not update mappable i.e. joining over other associations, we use its parent's parent id
            if (attribute.isUpdateMappable()) {
                subviewIdDescriptor = new TupleIdDescriptor();
            } else {
                subviewIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
            }
        } else {
            subviewIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
            subviewIdDescriptor.addIdPosition(flatViewIdPosition(attribute));
            subviewTupleIdDescriptor.addIdPosition(flatViewIdPosition(attribute));
        }
        int endTupleElementsToAdd = 0;
        String indexExpression = null;
        ViewTypeObjectBuilderTemplate<Object[]> indexTemplate = null;
        if (attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
            if (attribute.getKeyMappingExpression() != null) {
                MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
                indexExpression = mapperBuilder.getKeyMapping(subviewMappingPrefix, mapAttribute);
                if (mapAttribute.isKeySubview()) {
                    indexTemplate = new ViewTypeObjectBuilderTemplate<Object[]>(viewRoot, viewRootAlias, attributePath, subviewAliasPrefix, indexExpression, indexExpression, subviewTupleIdDescriptor, subviewIdDescriptor, 1, 0, viewJpqlMacro, embeddingViewJpqlMacro, (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) mapAttribute.getKeyInheritanceSubtypeMappings(), evm, ef, (ManagedViewTypeImplementor<Object[]>) mapAttribute.getKeyType(), null, proxyFactory);
                }
            } else if (attribute.getMappingIndexExpression() != null) {
                indexExpression = mapperBuilder.getIndexMapping(subviewMappingPrefix, (ListAttribute<?, ?>) attribute);
            }
            if (updatableObjectCache && managedViewType.getMappingType() == Type.MappingType.FLAT_VIEW) {
                if (indexExpression != null) {
                    endTupleElementsToAdd = 1;
                } else if (indexTemplate != null) {
                    endTupleElementsToAdd = indexTemplate.effectiveTupleSize;
                }
            }
        }
        Map<ManagedViewType<? extends Object[]>, String> inheritanceSubtypeMappings;
        if (attribute instanceof PluralAttribute<?, ?, ?>) {
            inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((PluralAttribute<?, ?, ?>) attribute).getElementInheritanceSubtypeMappings();
        } else {
            inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((SingularAttribute<?, ?>) attribute).getInheritanceSubtypeMappings();
        }
        String embeddingViewPath = mapperBuilder.getMapping();
        String oldViewPath = viewJpqlMacro.getViewPath();
        String oldEmbeddingViewPath = embeddingViewJpqlMacro.getEmbeddingViewPath();
        viewJpqlMacro.setViewPath(subviewMappingPrefix);
        embeddingViewJpqlMacro.setEmbeddingViewPath(embeddingViewPath);
        ViewTypeObjectBuilderTemplate<Object[]> template = new ViewTypeObjectBuilderTemplate<Object[]>(viewRoot, viewRootAlias, attributePath, subviewAliasPrefix, subviewMappingPrefix, subviewIdPrefix, subviewTupleIdDescriptor, subviewIdDescriptor, startIndex, endTupleElementsToAdd, viewJpqlMacro, embeddingViewJpqlMacro, inheritanceSubtypeMappings, evm, ef, managedViewType, null, proxyFactory);
        if (attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
            mapperBuilder.addMapper(new CorrelationMultisetTupleElementMapper(template, factory, correlationBasis, correlationExternalAlias, attributePath, mapperBuilder.getMapping(), indexExpression, indexTemplate, limiter));
        } else {
            mapperBuilder.addMappers(template.mappers);
            mapperBuilder.addSecondaryMappers(template.secondaryMappers);
            mapperBuilder.addTupleTransformatorFactory(template.tupleTransformatorFactory);
            mapperBuilder.addTupleTransformerFactory(new CorrelatedSubviewJoinTupleTransformerFactory(template, factory, correlationAlias, mapperBuilder.getMapping(), correlationBasis, correlationExternalAlias, attributePath, embeddingViewPath, attribute.getFetches(), limiter));
        }
        embeddingViewJpqlMacro.setEmbeddingViewPath(oldEmbeddingViewPath);
        viewJpqlMacro.setViewPath(oldViewPath);
        return new ViewTypeObjectBuilderTemplate[] { template, indexTemplate };
    } else if (attribute.getFetchStrategy() == FetchStrategy.SELECT) {
        String subviewAliasPrefix = mapperBuilder.getAlias(attribute, false);
        int viewRootIndex = viewRoot.hasSubtypes() ? 1 : 0;
        int embeddingViewIndex = (viewType.hasSubtypes() ? 1 : 0) + tupleOffset;
        int startIndex = tupleOffset + mapperBuilder.mapperIndex();
        Class<?> correlationBasisType = getCorrelationBasisType(attribute.getCorrelationBasisExpression(), AbstractAttribute.stripThisFromMapping(correlationBasis), attribute.getDeclaringType().getEntityViewRootTypes());
        Class<?> correlationBasisEntity = getCorrelationBasisEntityType(correlationBasisType);
        String correlationBasisExpression = AbstractAttribute.stripThisFromMapping(correlationBasis);
        String correlationKeyExpression = mapperBuilder.getMapping(attribute.getCorrelationBasisExpression(), correlationBasisEntity);
        String embeddingViewPath = mapperBuilder.getMapping();
        boolean correlatesThis = correlatesThis(evm, ef, managedTypeClass, attribute.getCorrelated(), correlationBasisExpression, attribute.getCorrelationPredicate(), attribute.getCorrelationKeyAlias());
        BasicUserTypeStringSupport<Object> correlationKeyExpressionBasicTypeType = getCorrelationKeyExpressionBasicTypeSupport(correlationBasisType, correlationBasisEntity);
        mapperBuilder.addMapper(createMapper(correlationKeyExpressionBasicTypeType, correlationKeyExpression, subviewAliasPrefix, attributePath, embeddingViewPath, embeddingViewJpqlMacro.getEmbeddingViewPath(), attribute.getFetches()));
        // We need a special mapping for the VIEW_ROOT/EMBEDDING_VIEW macro in certain cases
        viewRootIndex = addViewRootMappingIfNeeded(mapperBuilder, features, subviewAliasPrefix, attributePath, viewRootIndex);
        embeddingViewIndex = addEmbeddingViewMappingIfNeeded(mapperBuilder, features, subviewAliasPrefix, attributePath, embeddingViewIndex);
        if (batchSize == -1) {
            batchSize = 1;
        }
        if (attribute.isCollection()) {
            PluralAttribute<?, ?, ?> pluralAttribute = (PluralAttribute<?, ?, ?>) attribute;
            String[] indexFetches = EMPTY;
            Expression indexExpression = null;
            Correlator indexCorrelator = null;
            switch(pluralAttribute.getCollectionType()) {
                case COLLECTION:
                    if (pluralAttribute.isSorted()) {
                        throw new IllegalArgumentException("The collection attribute '" + pluralAttribute + "' can not be sorted!");
                    }
                    break;
                case LIST:
                    if (pluralAttribute.isSorted()) {
                        throw new IllegalArgumentException("The list attribute '" + pluralAttribute + "' can not be sorted!");
                    }
                    indexExpression = attribute.getMappingIndexExpression();
                    indexCorrelator = indexExpression == null ? null : new BasicCorrelator();
                    break;
                case SET:
                    break;
                case MAP:
                    MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
                    indexExpression = attribute.getKeyMappingExpression();
                    indexFetches = mapAttribute.getKeyFetches();
                    if (mapAttribute.isKeySubview()) {
                        indexCorrelator = new SubviewCorrelator((ManagedViewTypeImplementor<?>) mapAttribute.getKeyType(), null, evm, subviewAliasPrefix, attributePath);
                    } else {
                        indexCorrelator = new BasicCorrelator();
                    }
                    mapperBuilder.addTupleListTransformerFactory(new CorrelatedMapBatchTupleListTransformerFactory(new SubviewCorrelator(managedViewType, null, evm, subviewAliasPrefix, attributePath), viewRoot, viewType, correlationResult, factory, attributePath, attribute.getFetches(), correlatesThis, viewRootIndex, embeddingViewIndex, startIndex, batchSize, correlationBasisType, correlationBasisEntity, createLimiter(mapperBuilder, correlationAlias, attribute), indexFetches, indexExpression, indexCorrelator, attribute.getContainerAccumulator(), dirtyTracking));
                    return null;
                default:
                    throw new IllegalArgumentException("Unknown collection type: " + pluralAttribute.getCollectionType());
            }
            mapperBuilder.addTupleListTransformerFactory(new CorrelatedCollectionBatchTupleListTransformerFactory(new SubviewCorrelator(managedViewType, null, evm, subviewAliasPrefix, attributePath), viewRoot, viewType, correlationResult, factory, attributePath, attribute.getFetches(), correlatesThis, viewRootIndex, embeddingViewIndex, startIndex, batchSize, correlationBasisType, correlationBasisEntity, createLimiter(mapperBuilder, correlationAlias, attribute), indexFetches, indexExpression, indexCorrelator, attribute.getContainerAccumulator(), dirtyTracking));
        } else {
            mapperBuilder.addTupleListTransformerFactory(new CorrelatedSingularBatchTupleListTransformerFactory(new SubviewCorrelator(managedViewType, null, evm, subviewAliasPrefix, attributePath), viewRoot, viewType, correlationResult, factory, attributePath, attribute.getFetches(), correlatesThis, viewRootIndex, embeddingViewIndex, startIndex, batchSize, correlationBasisType, correlationBasisEntity, createLimiter(mapperBuilder, correlationAlias, attribute)));
        }
    } else if (attribute.getFetchStrategy() == FetchStrategy.SUBSELECT) {
        String subviewAliasPrefix = mapperBuilder.getAlias(attribute, false);
        int viewRootIndex = viewRoot.hasSubtypes() ? 1 : 0;
        int embeddingViewIndex = (viewType.hasSubtypes() ? 1 : 0) + tupleOffset;
        int startIndex = tupleOffset + mapperBuilder.mapperIndex();
        Class<?> correlationBasisType = getCorrelationBasisType(attribute.getCorrelationBasisExpression(), AbstractAttribute.stripThisFromMapping(correlationBasis), attribute.getDeclaringType().getEntityViewRootTypes());
        Class<?> correlationBasisEntity = getCorrelationBasisEntityType(correlationBasisType);
        String correlationBasisExpression = mapperBuilder.getMapping(attribute.getCorrelationBasisExpression());
        String correlationKeyExpression = mapperBuilder.getMapping(attribute.getCorrelationBasisExpression(), correlationBasisEntity);
        BasicUserTypeStringSupport<Object> correlationKeyExpressionBasicTypeType = getCorrelationKeyExpressionBasicTypeSupport(correlationBasisType, correlationBasisEntity);
        String embeddingViewPath = mapperBuilder.getMapping();
        mapperBuilder.addMapper(createMapper(correlationKeyExpressionBasicTypeType, correlationKeyExpression, subviewAliasPrefix, attributePath, embeddingViewPath, embeddingViewJpqlMacro.getEmbeddingViewPath(), attribute.getFetches()));
        if (attribute.isCollection()) {
            PluralAttribute<?, ?, ?> pluralAttribute = (PluralAttribute<?, ?, ?>) attribute;
            String[] indexFetches = EMPTY;
            Expression indexExpression = null;
            Correlator indexCorrelator = null;
            switch(pluralAttribute.getCollectionType()) {
                case COLLECTION:
                    if (pluralAttribute.isSorted()) {
                        throw new IllegalArgumentException("The collection attribute '" + pluralAttribute + "' can not be sorted!");
                    }
                    break;
                case LIST:
                    if (pluralAttribute.isSorted()) {
                        throw new IllegalArgumentException("The list attribute '" + pluralAttribute + "' can not be sorted!");
                    }
                    indexExpression = attribute.getMappingIndexExpression();
                    indexCorrelator = indexExpression == null ? null : new BasicCorrelator();
                    break;
                case SET:
                    break;
                case MAP:
                    MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
                    indexExpression = attribute.getKeyMappingExpression();
                    indexFetches = mapAttribute.getKeyFetches();
                    if (mapAttribute.isKeySubview()) {
                        indexCorrelator = new SubviewCorrelator((ManagedViewTypeImplementor<?>) mapAttribute.getKeyType(), null, evm, subviewAliasPrefix, attributePath);
                    } else {
                        indexCorrelator = new BasicCorrelator();
                    }
                    mapperBuilder.addTupleTransformerFactory(new CorrelatedMapSubselectTupleTransformerFactory(new SubviewCorrelator(managedViewType, null, evm, subviewAliasPrefix, attributePath), evm, viewRoot, viewRootAlias, viewType, embeddingViewPath, correlationResult, correlationBasisExpression, correlationKeyExpression, factory, attributePath, attribute.getFetches(), viewRootIndex, embeddingViewIndex, startIndex, correlationBasisType, correlationBasisEntity, createLimiter(mapperBuilder, correlationAlias, attribute), indexFetches, indexExpression, indexCorrelator, attribute.getContainerAccumulator(), dirtyTracking));
                    return null;
                default:
                    throw new IllegalArgumentException("Unknown collection type: " + pluralAttribute.getCollectionType());
            }
            mapperBuilder.addTupleTransformerFactory(new CorrelatedCollectionSubselectTupleTransformerFactory(new SubviewCorrelator(managedViewType, null, evm, subviewAliasPrefix, attributePath), evm, viewRoot, viewRootAlias, viewType, embeddingViewPath, correlationResult, correlationBasisExpression, correlationKeyExpression, factory, attributePath, attribute.getFetches(), viewRootIndex, embeddingViewIndex, startIndex, correlationBasisType, correlationBasisEntity, createLimiter(mapperBuilder, correlationAlias, attribute), indexFetches, indexExpression, indexCorrelator, attribute.getContainerAccumulator(), dirtyTracking));
        } else {
            mapperBuilder.addTupleTransformerFactory(new CorrelatedSingularSubselectTupleTransformerFactory(new SubviewCorrelator(managedViewType, null, evm, subviewAliasPrefix, attributePath), evm, viewRoot, viewRootAlias, viewType, embeddingViewPath, correlationResult, correlationBasisExpression, correlationKeyExpression, factory, attributePath, attribute.getFetches(), viewRootIndex, embeddingViewIndex, startIndex, correlationBasisType, correlationBasisEntity, createLimiter(mapperBuilder, correlationAlias, attribute)));
        }
    } else {
        throw new UnsupportedOperationException("Unknown fetch strategy: " + attribute.getFetchStrategy());
    }
    return null;
}
Also used : CorrelatedMapBatchTupleListTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedMapBatchTupleListTransformerFactory) SubviewCorrelator(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.SubviewCorrelator) CorrelatedSingularSubselectTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedSingularSubselectTupleTransformerFactory) CorrelationProviderFactory(com.blazebit.persistence.view.CorrelationProviderFactory) CorrelationMultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) Correlator(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.Correlator) SubviewCorrelator(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.SubviewCorrelator) BasicCorrelator(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.BasicCorrelator) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) CorrelatedSingularBatchTupleListTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedSingularBatchTupleListTransformerFactory) BasicUserTypeStringSupport(com.blazebit.persistence.view.spi.type.BasicUserTypeStringSupport) CorrelatedCollectionBatchTupleListTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedCollectionBatchTupleListTransformerFactory) CorrelatedSubviewJoinTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedSubviewJoinTupleTransformerFactory) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) Expression(com.blazebit.persistence.parser.expression.Expression) CorrelatedMapSubselectTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedMapSubselectTupleTransformerFactory) CorrelatedCollectionSubselectTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedCollectionSubselectTupleTransformerFactory) BasicCorrelator(com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.BasicCorrelator) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Aggregations

Expression (com.blazebit.persistence.parser.expression.Expression)1 CorrelationProviderFactory (com.blazebit.persistence.view.CorrelationProviderFactory)1 ManagedViewTypeImplementor (com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor)1 CorrelationMultisetTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper)1 BasicCorrelator (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.BasicCorrelator)1 CorrelatedCollectionBatchTupleListTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedCollectionBatchTupleListTransformerFactory)1 CorrelatedCollectionSubselectTupleTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedCollectionSubselectTupleTransformerFactory)1 CorrelatedMapBatchTupleListTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedMapBatchTupleListTransformerFactory)1 CorrelatedMapSubselectTupleTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedMapSubselectTupleTransformerFactory)1 CorrelatedSingularBatchTupleListTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedSingularBatchTupleListTransformerFactory)1 CorrelatedSingularSubselectTupleTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedSingularSubselectTupleTransformerFactory)1 CorrelatedSubviewJoinTupleTransformerFactory (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.CorrelatedSubviewJoinTupleTransformerFactory)1 Correlator (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.Correlator)1 SubviewCorrelator (com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation.SubviewCorrelator)1 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)1 MapAttribute (com.blazebit.persistence.view.metamodel.MapAttribute)1 PluralAttribute (com.blazebit.persistence.view.metamodel.PluralAttribute)1 ViewType (com.blazebit.persistence.view.metamodel.ViewType)1 BasicUserTypeStringSupport (com.blazebit.persistence.view.spi.type.BasicUserTypeStringSupport)1 HashMap (java.util.HashMap)1