Search in sources :

Example 6 with MapAttribute

use of com.blazebit.persistence.view.metamodel.MapAttribute in project blaze-persistence by Blazebit.

the class ViewTypeObjectBuilderTemplate method applyMapping.

@SuppressWarnings("unchecked")
private void applyMapping(AbstractAttribute<?, ?> attribute, String parentAttributePath, TupleElementMapperBuilder mapperBuilder, Set<Feature> features, TupleIdDescriptor tupleIdDescriptor, ViewJpqlMacro viewJpqlMacro, EmbeddingViewJpqlMacro embeddingViewJpqlMacro, ExpressionFactory ef) {
    String attributePath = getAttributePath(parentAttributePath, attribute, false);
    int batchSize = attribute.getBatchSize();
    if (batchSize == -1) {
        batchSize = attribute.getDeclaringType().getDefaultBatchSize();
    }
    if (attribute.isSubquery()) {
        applySubqueryMapping((SubqueryAttribute<? super T, ?>) attribute, attributePath, mapperBuilder, embeddingViewJpqlMacro);
    } else {
        if (attribute.isCollection()) {
            PluralAttribute<? super T, ?, ?> pluralAttribute = (PluralAttribute<? super T, ?, ?>) attribute;
            TypeConverter<Object, Object> keyConverter = null;
            TypeConverter<Object, Object> valueConverter = (TypeConverter<Object, Object>) pluralAttribute.getElementType().getConverter();
            boolean listKey = pluralAttribute.isIndexed() && pluralAttribute instanceof ListAttribute<?, ?>;
            boolean mapKey = pluralAttribute.isIndexed() && pluralAttribute instanceof MapAttribute<?, ?, ?>;
            int startIndex = tupleOffset + mapperBuilder.mapperIndex();
            int valueStartIndex = startIndex + 1;
            if (pluralAttribute.getFetchStrategy() == FetchStrategy.JOIN) {
                if (listKey) {
                    MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                    features.add(Feature.INDEXED_COLLECTIONS);
                    applyIndexCollectionFunctionMapping(IntegerBasicUserType.INSTANCE, mappingAttribute, attributePath, mapperBuilder, embeddingViewJpqlMacro);
                } else if (mapKey) {
                    MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                    features.add(Feature.INDEXED_COLLECTIONS);
                    MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) pluralAttribute;
                    keyConverter = (TypeConverter<Object, Object>) mapAttribute.getKeyType().getConverter();
                    if (mapAttribute.isKeySubview()) {
                        features.add(Feature.SUBVIEWS);
                        ManagedViewTypeImpl<Object[]> managedViewType = (ManagedViewTypeImpl<Object[]>) mapAttribute.getKeyType();
                        applySubviewMapping(mappingAttribute, attributePath, tupleIdDescriptor, managedViewType, mapperBuilder, viewJpqlMacro, embeddingViewJpqlMacro, ef, true, true);
                        valueStartIndex = tupleOffset + mapperBuilder.mapperIndex();
                    } else {
                        applyIndexCollectionFunctionMapping(TypeUtils.forType(mapAttribute.getKeyType()), mappingAttribute, attributePath, mapperBuilder, embeddingViewJpqlMacro);
                    }
                }
            }
            boolean dirtyTracking = pluralAttribute instanceof MethodAttribute<?, ?> && attribute.needsDirtyTracker();
            if (pluralAttribute.isSubview()) {
                features.add(Feature.SUBVIEWS);
                TupleIdDescriptor newTupleIdDescriptor;
                if ((listKey || mapKey) && pluralAttribute.getFetchStrategy() == FetchStrategy.JOIN && !pluralAttribute.isCorrelated()) {
                    newTupleIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
                    newTupleIdDescriptor.addIdPosition(startIndex);
                } else {
                    newTupleIdDescriptor = tupleIdDescriptor;
                }
                if (pluralAttribute.isCorrelated() || (pluralAttribute.getFetchStrategy() != FetchStrategy.JOIN || attribute.getLimitExpression() != null) && pluralAttribute.getFetchStrategy() != FetchStrategy.MULTISET) {
                    ManagedViewTypeImplementor<Object> managedViewType = (ManagedViewTypeImplementor<Object>) pluralAttribute.getElementType();
                    if (attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
                        boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
                        boolean nullIfEmpty = managedViewType instanceof ViewType<?>;
                        ViewTypeObjectBuilderTemplate<Object[]>[] templates = applyCorrelatedSubviewMapping(attribute, attributePath, tupleIdDescriptor, (ManagedViewTypeImplementor<Object[]>) (ManagedViewTypeImplementor<?>) managedViewType, mapperBuilder, features, viewJpqlMacro, embeddingViewJpqlMacro, ef, batchSize, false);
                        ViewTypeObjectBuilderTemplate<Object[]> subviewTemplate = templates[0];
                        ViewTypeObjectBuilderTemplate<Object[]> indexTemplate = templates[1];
                        SubviewTupleTransformerFactory indexTransformerFactory = null;
                        BasicUserTypeStringSupport<?> indexBasicTypeSupport = null;
                        if (indexTemplate != null) {
                            boolean updatableKeyObjectCache = indexTemplate.viewType.isUpdatable() || indexTemplate.viewType.isCreatable();
                            indexTransformerFactory = new SubviewTupleTransformerFactory(attributePath, indexTemplate, updatableKeyObjectCache, true);
                        } else if (mapKey) {
                            indexBasicTypeSupport = TypeUtils.forType(((MapAttribute<?, ?, ?>) attribute).getKeyType());
                        } else if (listKey) {
                            indexBasicTypeSupport = IntegerBasicUserType.INSTANCE;
                        }
                        mapperBuilder.addTupleTransformerFactory(new CollectionMultisetTupleTransformerFactory(startIndex, null, attributePath, getMultisetResultAlias(attributePath), valueConverter, attribute.getContainerAccumulator(), dirtyTracking, subviewTemplate, indexTemplate, managedViewType.hasSelectOrSubselectFetchedAttributes(), new SubviewTupleTransformerFactory(attributePath, subviewTemplate, updatableObjectCache, nullIfEmpty), indexTransformerFactory, null, indexBasicTypeSupport));
                    } else {
                        applyCorrelatedSubviewMapping(attribute, attributePath, newTupleIdDescriptor, (ManagedViewTypeImplementor<Object[]>) (ManagedViewTypeImplementor<?>) managedViewType, mapperBuilder, features, viewJpqlMacro, embeddingViewJpqlMacro, ef, batchSize, dirtyTracking);
                    }
                } else {
                    MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                    ManagedViewTypeImplementor<Object[]> managedViewType = (ManagedViewTypeImplementor<Object[]>) pluralAttribute.getElementType();
                    boolean nullIfEmpty = managedViewType instanceof ViewType<?> || !listKey && !mapKey;
                    if (pluralAttribute.getFetchStrategy() == FetchStrategy.MULTISET) {
                        boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
                        String mapping = mapperBuilder.getMapping(mappingAttribute);
                        ViewTypeObjectBuilderTemplate<Object[]>[] templates = applySubviewMapping(mappingAttribute, attributePath, newTupleIdDescriptor, managedViewType, mapperBuilder, viewJpqlMacro, embeddingViewJpqlMacro, ef, false, nullIfEmpty);
                        ViewTypeObjectBuilderTemplate<Object[]> subviewTemplate = templates[0];
                        ViewTypeObjectBuilderTemplate<Object[]> indexTemplate = templates[1];
                        SubviewTupleTransformerFactory indexTransformerFactory = null;
                        BasicUserTypeStringSupport<?> indexBasicTypeSupport = null;
                        if (indexTemplate != null) {
                            boolean updatableKeyObjectCache = indexTemplate.viewType.isUpdatable() || indexTemplate.viewType.isCreatable();
                            indexTransformerFactory = new SubviewTupleTransformerFactory(attributePath, indexTemplate, updatableKeyObjectCache, true);
                        } else if (mapKey) {
                            indexBasicTypeSupport = TypeUtils.forType(((MapAttribute<?, ?, ?>) attribute).getKeyType());
                        } else if (listKey) {
                            indexBasicTypeSupport = IntegerBasicUserType.INSTANCE;
                        }
                        mapperBuilder.addTupleTransformerFactory(new CollectionMultisetTupleTransformerFactory(startIndex, mapping, attributePath, getMultisetResultAlias(attributePath), valueConverter, attribute.getContainerAccumulator(), dirtyTracking, subviewTemplate, indexTemplate, managedViewType.hasSelectOrSubselectFetchedAttributes(), new SubviewTupleTransformerFactory(attributePath, subviewTemplate, updatableObjectCache, nullIfEmpty), indexTransformerFactory, null, indexBasicTypeSupport));
                    } else {
                        // Obviously, we produce null if the object type is identifiable i.e. a ViewType and it is empty = null id
                        // Additionally, we also consider empty embeddables as null when we have a non-indexed collection so we can filter out these elements
                        applySubviewMapping(mappingAttribute, attributePath, newTupleIdDescriptor, managedViewType, mapperBuilder, viewJpqlMacro, embeddingViewJpqlMacro, ef, false, nullIfEmpty);
                    }
                }
            } else if (mapKey) {
                MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                applyCollectionFunctionMapping(TypeUtils.forType(getType(mappingAttribute)), mappingAttribute, attributePath, mapperBuilder, mappingAttribute.getFetches(), embeddingViewJpqlMacro);
            } else {
                // TODO: Multiset basic fetching?
                if (pluralAttribute.isCorrelated() || attribute.getFetchStrategy() == FetchStrategy.JOIN && !attribute.getOrderByItems().isEmpty() || pluralAttribute.getFetchStrategy() != FetchStrategy.JOIN && pluralAttribute.getFetchStrategy() != FetchStrategy.MULTISET) {
                    applyBasicCorrelatedMapping(attribute, attributePath, mapperBuilder, features, ef, batchSize, dirtyTracking, embeddingViewJpqlMacro);
                } else {
                    MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                    applyBasicMapping(mappingAttribute, attributePath, mapperBuilder, embeddingViewJpqlMacro);
                }
            }
            if (pluralAttribute.getFetchStrategy() == FetchStrategy.JOIN) {
                if (listKey) {
                    if (pluralAttribute.isSorted()) {
                        throw new IllegalArgumentException("The list attribute '" + pluralAttribute + "' can not be sorted!");
                    } else {
                        mapperBuilder.addTupleListTransformer(new IndexedTupleListTransformer(tupleIdDescriptor.createIdPositions(), startIndex, valueStartIndex, attribute.getContainerAccumulator(), dirtyTracking, null, valueConverter));
                    }
                } else if (mapKey) {
                    mapperBuilder.addTupleListTransformer(new IndexedTupleListTransformer(tupleIdDescriptor.createIdPositions(), startIndex, valueStartIndex, attribute.getContainerAccumulator(), dirtyTracking, keyConverter, valueConverter));
                } else {
                    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!");
                            }
                            break;
                        case SET:
                            break;
                        case MAP:
                            throw new IllegalArgumentException("Ignoring the index on the attribute '" + pluralAttribute + "' is not possible!");
                        default:
                            throw new IllegalArgumentException("Unknown collection type: " + pluralAttribute.getCollectionType());
                    }
                    mapperBuilder.addTupleListTransformer(new NonIndexedTupleListTransformer(tupleIdDescriptor.createIdPositions(), startIndex, attribute.getCollectionInstantiator(), dirtyTracking, valueConverter));
                }
            }
        } else if (attribute.isQueryParameter()) {
            MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
            features.add(Feature.PARAMETERS);
            applyQueryParameterMapping(mappingAttribute, mapperBuilder);
        } else if (attribute.isSubview()) {
            features.add(Feature.SUBVIEWS);
            boolean nullIfEmpty = !((SingularAttribute<?, ?>) attribute).isCreateEmptyFlatView();
            if (attribute.isCorrelated() || attribute.getFetchStrategy() == FetchStrategy.JOIN && !attribute.getOrderByItems().isEmpty() || attribute.getFetchStrategy() != FetchStrategy.JOIN && attribute.getFetchStrategy() != FetchStrategy.MULTISET) {
                ManagedViewTypeImplementor<Object> managedViewType = (ManagedViewTypeImplementor<Object>) ((SingularAttribute<?, ?>) attribute).getType();
                if (attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
                    int startIndex = tupleOffset + mapperBuilder.mapperIndex();
                    boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
                    ViewTypeObjectBuilderTemplate<Object[]> subviewTemplate = applyCorrelatedSubviewMapping(attribute, attributePath, tupleIdDescriptor, (ManagedViewTypeImplementor<Object[]>) (ManagedViewTypeImplementor<?>) managedViewType, mapperBuilder, features, viewJpqlMacro, embeddingViewJpqlMacro, ef, batchSize, false)[0];
                    TypeConverter<Object, Object> elementConverter = (TypeConverter<Object, Object>) (TypeConverter<?, ?>) managedViewType.getConverter();
                    mapperBuilder.addTupleTransformerFactory(new SingularMultisetTupleTransformerFactory(startIndex, null, attributePath, getMultisetResultAlias(attributePath), elementConverter, subviewTemplate, managedViewType.hasSelectOrSubselectFetchedAttributes(), new SubviewTupleTransformerFactory(attributePath, subviewTemplate, updatableObjectCache, nullIfEmpty)));
                } else {
                    applyCorrelatedSubviewMapping(attribute, attributePath, tupleIdDescriptor, (ManagedViewTypeImplementor<Object[]>) (ManagedViewTypeImplementor<?>) managedViewType, mapperBuilder, features, viewJpqlMacro, embeddingViewJpqlMacro, ef, batchSize, false);
                }
            } else {
                MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                ManagedViewTypeImplementor<Object[]> managedViewType = (ManagedViewTypeImplementor<Object[]>) ((SingularAttribute<?, ?>) attribute).getType();
                if (attribute.getFetchStrategy() == FetchStrategy.MULTISET) {
                    int startIndex = tupleOffset + mapperBuilder.mapperIndex();
                    boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
                    String mapping = mapperBuilder.getMapping(mappingAttribute);
                    ViewTypeObjectBuilderTemplate<Object[]> subviewTemplate = applySubviewMapping(mappingAttribute, attributePath, tupleIdDescriptor, managedViewType, mapperBuilder, viewJpqlMacro, embeddingViewJpqlMacro, ef, false, nullIfEmpty)[0];
                    TypeConverter<Object, Object> elementConverter = (TypeConverter<Object, Object>) (TypeConverter<?, ?>) managedViewType.getConverter();
                    mapperBuilder.addTupleTransformerFactory(new SingularMultisetTupleTransformerFactory(startIndex, mapping, attributePath, getMultisetResultAlias(attributePath), elementConverter, subviewTemplate, managedViewType.hasSelectOrSubselectFetchedAttributes(), new SubviewTupleTransformerFactory(attributePath, subviewTemplate, updatableObjectCache, nullIfEmpty)));
                } else {
                    applySubviewMapping(mappingAttribute, attributePath, tupleIdDescriptor, managedViewType, mapperBuilder, viewJpqlMacro, embeddingViewJpqlMacro, ef, false, nullIfEmpty);
                }
            }
        } else {
            if (attribute.isCorrelated() || attribute.getFetchStrategy() == FetchStrategy.JOIN && !attribute.getOrderByItems().isEmpty() || attribute.getFetchStrategy() != FetchStrategy.JOIN && attribute.getFetchStrategy() != FetchStrategy.MULTISET) {
                applyBasicCorrelatedMapping(attribute, attributePath, mapperBuilder, features, ef, batchSize, false, embeddingViewJpqlMacro);
            } else {
                MappingAttribute<? super T, ?> mappingAttribute = (MappingAttribute<? super T, ?>) attribute;
                applyBasicMapping(mappingAttribute, attributePath, mapperBuilder, embeddingViewJpqlMacro);
            }
        }
    }
}
Also used : MappingAttribute(com.blazebit.persistence.view.metamodel.MappingAttribute) NonIndexedTupleListTransformer(com.blazebit.persistence.view.impl.objectbuilder.transformer.NonIndexedTupleListTransformer) IndexedTupleListTransformer(com.blazebit.persistence.view.impl.objectbuilder.transformer.IndexedTupleListTransformer) NonIndexedTupleListTransformer(com.blazebit.persistence.view.impl.objectbuilder.transformer.NonIndexedTupleListTransformer) ManagedViewTypeImpl(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImpl) SubviewTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.SubviewTupleTransformerFactory) CollectionMultisetTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.CollectionMultisetTupleTransformerFactory) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) TypeConverter(com.blazebit.persistence.view.spi.type.TypeConverter) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) SingularMultisetTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.SingularMultisetTupleTransformerFactory) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Example 7 with MapAttribute

use of com.blazebit.persistence.view.metamodel.MapAttribute in project blaze-persistence by Blazebit.

the class ViewTypeObjectBuilderTemplate method applyIndexCollectionFunctionMapping.

private void applyIndexCollectionFunctionMapping(BasicUserTypeStringSupport<?> basicUserTypeStringSupport, MappingAttribute<? super T, ?> mappingAttribute, String attributePath, TupleElementMapperBuilder mapperBuilder, EmbeddingViewJpqlMacro embeddingViewJpqlMacro) {
    String expression;
    String[] fetches = EMPTY;
    if (mappingAttribute instanceof MapAttribute<?, ?, ?>) {
        expression = mapperBuilder.getKeyMapping((MapAttribute<?, ?, ?>) mappingAttribute);
        fetches = ((MapAttribute<?, ?, ?>) mappingAttribute).getKeyFetches();
    } else {
        expression = mapperBuilder.getIndexMapping((ListAttribute<?, ?>) mappingAttribute);
    }
    String alias = mapperBuilder.getAlias(mappingAttribute, true);
    TupleElementMapper mapper = createMapper(basicUserTypeStringSupport, expression, alias, attributePath, mapperBuilder.getMapping(), embeddingViewJpqlMacro.getEmbeddingViewPath(), fetches);
    mapperBuilder.addMapper(mapper);
}
Also used : MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) ParameterizedSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedSubqueryTupleElementMapper) TupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.TupleElementMapper) ParameterizedExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedExpressionSubqueryTupleElementMapper) MultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper) AliasExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasExpressionSubqueryTupleElementMapper) ParameterizedExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedExpressionCorrelationJoinTupleElementMapper) ParameterizedAliasExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedAliasExpressionSubqueryTupleElementMapper) ParameterizedAliasSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedAliasSubqueryTupleElementMapper) ExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionSubqueryTupleElementMapper) ExpressionTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionTupleElementMapper) CorrelationMultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper) SimpleSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.SimpleSubqueryTupleElementMapper) ExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionCorrelationJoinTupleElementMapper) AliasExpressionTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasExpressionTupleElementMapper) AliasSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasSubqueryTupleElementMapper) ConstrainedTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ConstrainedTupleElementMapper) ListAttribute(com.blazebit.persistence.view.metamodel.ListAttribute)

Example 8 with MapAttribute

use of com.blazebit.persistence.view.metamodel.MapAttribute in project blaze-persistence by Blazebit.

the class ViewTypeObjectBuilderTemplate method applySubviewMapping.

@SuppressWarnings("unchecked")
private ViewTypeObjectBuilderTemplate<Object[]>[] applySubviewMapping(MappingAttribute<? super T, ?> mappingAttribute, String subviewAttributePath, TupleIdDescriptor tupleIdDescriptor, ManagedViewTypeImplementor<Object[]> managedViewType, TupleElementMapperBuilder mapperBuilder, ViewJpqlMacro viewJpqlMacro, EmbeddingViewJpqlMacro embeddingViewJpqlMacro, ExpressionFactory ef, boolean isKey, boolean nullIfEmpty) {
    AbstractAttribute<?, ?> attribute = (AbstractAttribute<?, ?>) mappingAttribute;
    String subviewAliasPrefix = mapperBuilder.getAlias(mappingAttribute, isKey);
    String subviewMappingPrefix;
    String subviewIdPrefix;
    int startIndex;
    if (mappingAttribute.getFetchStrategy() == FetchStrategy.MULTISET) {
        startIndex = 0;
    } else {
        startIndex = tupleOffset + mapperBuilder.mapperIndex();
    }
    boolean updatableObjectCache = managedViewType.isUpdatable() || managedViewType.isCreatable();
    TupleIdDescriptor subviewTupleIdDescriptor = new TupleIdDescriptor(tupleIdDescriptor);
    TupleIdDescriptor subviewIdDescriptor;
    String multisetCorrelationExpression;
    if (mappingAttribute.getFetchStrategy() != FetchStrategy.MULTISET) {
        if (isKey) {
            subviewMappingPrefix = mapperBuilder.getKeyMapping((MapAttribute<?, ?, ?>) mappingAttribute);
        } else {
            subviewMappingPrefix = mapperBuilder.getMapping(mappingAttribute);
        }
        subviewIdPrefix = subviewMappingPrefix;
        multisetCorrelationExpression = null;
    } else {
        // Must be in sync with com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper.applyMapping
        subviewMappingPrefix = getMultisetResultAlias(subviewAttributePath);
        subviewIdPrefix = subviewMappingPrefix;
        multisetCorrelationExpression = mapperBuilder.getMapping(mappingAttribute);
    }
    String oldViewPath = viewJpqlMacro.getViewPath();
    viewJpqlMacro.setViewPath(subviewMappingPrefix);
    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(mappingAttribute));
        subviewTupleIdDescriptor.addIdPosition(flatViewIdPosition(mappingAttribute));
    }
    int endTupleElementsToAdd = 0;
    String indexExpression = null;
    ViewTypeObjectBuilderTemplate<Object[]> indexTemplate = null;
    if (mappingAttribute.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, subviewAttributePath, 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 (isKey) {
        inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((MapAttribute<?, ?, ?>) mappingAttribute).getKeyInheritanceSubtypeMappings();
    } else if (mappingAttribute instanceof PluralAttribute<?, ?, ?>) {
        inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((PluralAttribute<?, ?, ?>) mappingAttribute).getElementInheritanceSubtypeMappings();
    } else {
        inheritanceSubtypeMappings = (Map<ManagedViewType<? extends Object[]>, String>) (Map<?, ?>) ((SingularAttribute<?, ?>) mappingAttribute).getInheritanceSubtypeMappings();
    }
    String embeddingViewPath = mapperBuilder.getMapping();
    String oldEmbeddingViewPath = embeddingViewJpqlMacro.getEmbeddingViewPath();
    embeddingViewJpqlMacro.setEmbeddingViewPath(embeddingViewPath);
    ViewTypeObjectBuilderTemplate<Object[]> template = new ViewTypeObjectBuilderTemplate<Object[]>(viewRoot, viewRootAlias, subviewAttributePath, subviewAliasPrefix, subviewMappingPrefix, subviewIdPrefix, subviewTupleIdDescriptor, subviewIdDescriptor, startIndex, endTupleElementsToAdd, viewJpqlMacro, embeddingViewJpqlMacro, inheritanceSubtypeMappings, evm, ef, managedViewType, null, proxyFactory);
    ViewTypeObjectBuilderTemplate<Object[]>[] templates = null;
    if (mappingAttribute.getFetchStrategy() == FetchStrategy.MULTISET) {
        String multisetResultAlias = getMultisetResultAlias(subviewAttributePath);
        mapperBuilder.addMapper(new MultisetTupleElementMapper(template, multisetCorrelationExpression, subviewAttributePath, multisetResultAlias, embeddingViewPath, indexExpression, indexTemplate, createLimiter(mapperBuilder, multisetResultAlias, mappingAttribute)));
        templates = new ViewTypeObjectBuilderTemplate[] { template, indexTemplate };
    } else {
        mapperBuilder.addMappers(template.mappers);
        mapperBuilder.addSecondaryMappers(template.secondaryMappers);
        mapperBuilder.addTupleTransformatorFactory(template.tupleTransformatorFactory);
        mapperBuilder.addTupleTransformerFactory(new SubviewTupleTransformerFactory(subviewAttributePath, template, updatableObjectCache, nullIfEmpty));
    }
    embeddingViewJpqlMacro.setEmbeddingViewPath(oldEmbeddingViewPath);
    viewJpqlMacro.setViewPath(oldViewPath);
    return templates;
}
Also used : ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) MultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper) CorrelationMultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) SingularAttribute(com.blazebit.persistence.view.metamodel.SingularAttribute) AbstractAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractAttribute) SubviewTupleTransformerFactory(com.blazebit.persistence.view.impl.objectbuilder.transformer.SubviewTupleTransformerFactory) 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)

Example 9 with MapAttribute

use of com.blazebit.persistence.view.metamodel.MapAttribute in project blaze-persistence by Blazebit.

the class ViewTypeObjectBuilderTemplate method applyBasicCorrelatedMapping.

private void applyBasicCorrelatedMapping(AbstractAttribute<?, ?> attribute, String attributePath, TupleElementMapperBuilder mapperBuilder, Set<Feature> features, ExpressionFactory ef, int batchSize, boolean dirtyTracking, EmbeddingViewJpqlMacro embeddingViewJpqlMacro) {
    Expression correlationResult = attribute.getCorrelationResultExpression();
    CorrelationProviderFactory factory = attribute.getCorrelationProviderFactory();
    String correlationBasis = attribute.getCorrelationBasis();
    String correlationAlias = CorrelationProviderHelper.getDefaultCorrelationAlias(attributePath);
    if (attribute.getFetchStrategy() == FetchStrategy.JOIN) {
        String alias = mapperBuilder.getAlias(attribute, false);
        correlationBasis = mapperBuilder.getMapping(attribute.getCorrelationBasisExpression());
        TupleElementMapper mapper;
        String joinBase = mapperBuilder.getMapping();
        String joinCorrelationAttributePath = mapperBuilder.getJoinCorrelationAttributePath(attributePath);
        String embeddingViewPath = joinBase;
        if (factory.isParameterized()) {
            mapper = new ParameterizedExpressionCorrelationJoinTupleElementMapper(factory, ef, joinBase, correlationBasis, attribute.getCorrelationResultExpression(), alias, joinCorrelationAttributePath, embeddingViewPath, attribute.getFetches(), createLimiter(mapperBuilder, correlationAlias, attribute), viewRoot.getEntityViewRootTypes().keySet());
        } else {
            mapper = new ExpressionCorrelationJoinTupleElementMapper(factory.create(null, null), ef, joinBase, correlationBasis, attribute.getCorrelationResultExpression(), alias, joinCorrelationAttributePath, embeddingViewPath, attribute.getFetches(), createLimiter(mapperBuilder, correlationAlias, attribute), viewRoot.getEntityViewRootTypes().keySet());
        }
        mapperBuilder.addMapper(mapper);
    } else if (attribute.getFetchStrategy() == FetchStrategy.SELECT) {
        String subviewAliasPrefix = mapperBuilder.getAlias(attribute, false);
        int viewRootIndex = viewRoot.hasSubtypes() ? 1 : 0;
        int embeddingViewIndex = 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 BasicCorrelator(), 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;
                default:
                    throw new IllegalArgumentException("Unknown collection type: " + pluralAttribute.getCollectionType());
            }
            mapperBuilder.addTupleListTransformerFactory(new CorrelatedCollectionBatchTupleListTransformerFactory(new BasicCorrelator(), 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 BasicCorrelator(), 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 = 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 BasicCorrelator(), 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;
                default:
                    throw new IllegalArgumentException("Unknown collection type: " + pluralAttribute.getCollectionType());
            }
            mapperBuilder.addTupleTransformerFactory(new CorrelatedCollectionSubselectTupleTransformerFactory(new BasicCorrelator(), 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 BasicCorrelator(), 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());
    }
}
Also used : ParameterizedExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedExpressionCorrelationJoinTupleElementMapper) ExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionCorrelationJoinTupleElementMapper) 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) ParameterizedExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedExpressionCorrelationJoinTupleElementMapper) 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) 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) ParameterizedSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedSubqueryTupleElementMapper) TupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.TupleElementMapper) ParameterizedExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedExpressionSubqueryTupleElementMapper) MultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper) AliasExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasExpressionSubqueryTupleElementMapper) ParameterizedExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedExpressionCorrelationJoinTupleElementMapper) ParameterizedAliasExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedAliasExpressionSubqueryTupleElementMapper) ParameterizedAliasSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ParameterizedAliasSubqueryTupleElementMapper) ExpressionSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionSubqueryTupleElementMapper) ExpressionTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionTupleElementMapper) CorrelationMultisetTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper) SimpleSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.SimpleSubqueryTupleElementMapper) ExpressionCorrelationJoinTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ExpressionCorrelationJoinTupleElementMapper) AliasExpressionTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasExpressionTupleElementMapper) AliasSubqueryTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasSubqueryTupleElementMapper) ConstrainedTupleElementMapper(com.blazebit.persistence.view.impl.objectbuilder.mapper.ConstrainedTupleElementMapper)

Example 10 with MapAttribute

use of com.blazebit.persistence.view.metamodel.MapAttribute 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

MapAttribute (com.blazebit.persistence.view.metamodel.MapAttribute)15 PluralAttribute (com.blazebit.persistence.view.metamodel.PluralAttribute)13 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)11 SingularAttribute (com.blazebit.persistence.view.metamodel.SingularAttribute)5 ViewType (com.blazebit.persistence.view.metamodel.ViewType)5 HashMap (java.util.HashMap)5 Map (java.util.Map)5 ManagedViewTypeImplementor (com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor)4 CorrelationMultisetTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.CorrelationMultisetTupleElementMapper)4 EntityMetamodel (com.blazebit.persistence.parser.EntityMetamodel)3 MultisetTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper)3 Expression (com.blazebit.persistence.parser.expression.Expression)2 CorrelationProviderFactory (com.blazebit.persistence.view.CorrelationProviderFactory)2 MapEntityViewBuilderListener (com.blazebit.persistence.view.MapEntityViewBuilderListener)2 MapKeyEntityViewBuilderListener (com.blazebit.persistence.view.MapKeyEntityViewBuilderListener)2 AbstractAttribute (com.blazebit.persistence.view.impl.metamodel.AbstractAttribute)2 AliasExpressionSubqueryTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasExpressionSubqueryTupleElementMapper)2 AliasExpressionTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasExpressionTupleElementMapper)2 AliasSubqueryTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.AliasSubqueryTupleElementMapper)2 ConstrainedTupleElementMapper (com.blazebit.persistence.view.impl.objectbuilder.mapper.ConstrainedTupleElementMapper)2