Search in sources :

Example 1 with MutableViewJpqlMacro

use of com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro in project blaze-persistence by Blazebit.

the class Mappers method forViewConvertToViewAttributeMapping.

public static <S, T> Mapper<S, T> forViewConvertToViewAttributeMapping(EntityViewManagerImpl evm, ViewType<S> sourceViewType, ViewType<T> targetViewType, Map<String, String> mapping, Mapper<S, T> additionalMapper) {
    List<Mapper<S, T>> mappers = new ArrayList<>();
    ExpressionFactory ef = evm.getCriteriaBuilderFactory().getService(ExpressionFactory.class);
    for (MethodAttribute<?, ?> attribute : targetViewType.getAttributes()) {
        if (attribute.isUpdatable() && attribute instanceof MappingAttribute<?, ?> && attribute instanceof SingularAttribute<?, ?>) {
            for (Map.Entry<String, String> entry : mapping.entrySet()) {
                if (entry.getValue().equals(((MappingAttribute) attribute).getMapping())) {
                    Type<?> attributeType = ((SingularAttribute<?, ?>) attribute).getType();
                    AttributeAccessor entityAccessor;
                    if (entry.getKey().isEmpty()) {
                        entityAccessor = Accessors.forEntityMapping(evm, sourceViewType.getEntityClass(), ((MappingAttribute<?, ?>) sourceViewType.getIdAttribute()).getMapping());
                    } else {
                        entityAccessor = Accessors.forEntityMapping(evm, sourceViewType.getEntityClass(), entry.getKey());
                    }
                    AttributeAccessor targetAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
                    if (attributeType instanceof ViewType<?>) {
                        ViewType<?> viewType = (ViewType<?>) attributeType;
                        Type<?> attributeViewIdType = ((SingularAttribute<?, ?>) viewType.getIdAttribute()).getType();
                        EntityTupleizer entityTupleizer = null;
                        ObjectBuilder<?> idViewBuilder = null;
                        if (attributeViewIdType instanceof ManagedViewType<?>) {
                            entityTupleizer = new DefaultEntityTupleizer(evm, (ManagedViewType<?>) attributeViewIdType);
                            idViewBuilder = (ObjectBuilder<Object>) evm.getTemplate(new MacroConfigurationExpressionFactory(ef, ef.getDefaultMacroConfiguration()), (ManagedViewTypeImplementor<?>) attributeViewIdType, null, null, new MutableViewJpqlMacro(), null, new MutableEmbeddingViewJpqlMacro(), 0).createObjectBuilder(null, null, null, 0, false, false);
                        }
                        mappers.add(new ReferenceViewAttributeMapper<S, T>(evm, entityAccessor, viewType.getJavaType(), entityTupleizer, targetAttributeAccessor, idViewBuilder));
                    } else {
                        mappers.add((Mapper<S, T>) new AttributeMapper<>(Collections.singletonList(entityAccessor), Collections.singletonList(targetAttributeAccessor)));
                    }
                }
            }
        }
    }
    if (mappers.isEmpty()) {
        return additionalMapper;
    }
    return new CompositeMapper<>(mappers.toArray(new Mapper[mappers.size()]));
}
Also used : DefaultEntityTupleizer(com.blazebit.persistence.view.impl.update.DefaultEntityTupleizer) EntityTupleizer(com.blazebit.persistence.view.impl.entity.EntityTupleizer) ArrayList(java.util.ArrayList) MappingAttribute(com.blazebit.persistence.view.metamodel.MappingAttribute) MutableEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro) DefaultEntityTupleizer(com.blazebit.persistence.view.impl.update.DefaultEntityTupleizer) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ExpressionFactory(com.blazebit.persistence.parser.expression.ExpressionFactory) MacroConfigurationExpressionFactory(com.blazebit.persistence.view.impl.MacroConfigurationExpressionFactory) MutableViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) MacroConfigurationExpressionFactory(com.blazebit.persistence.view.impl.MacroConfigurationExpressionFactory) SingularAttribute(com.blazebit.persistence.view.metamodel.SingularAttribute) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor) HashMap(java.util.HashMap) Map(java.util.Map) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Example 2 with MutableViewJpqlMacro

use of com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro in project blaze-persistence by Blazebit.

the class AbstractCorrelatedBatchTupleListTransformer method applyAndGetCorrelationRoot.

private String applyAndGetCorrelationRoot(BatchCorrelationMode batchCorrelationMode) {
    Class<?> viewRootEntityClass = viewRootType.getEntityClass();
    Class<?> embeddingViewEntityClass = embeddingViewType.getEntityClass();
    String viewRootIdAttributePath = getEntityIdName(viewRootEntityClass);
    String embeddingViewIdAttributePath = getEntityIdName(embeddingViewEntityClass);
    FullQueryBuilder<?, ?> queryBuilder = entityViewConfiguration.getCriteriaBuilder();
    Map<String, Object> optionalParameters = entityViewConfiguration.getOptionalParameters();
    Class<?> correlationBasisEntityType;
    String viewRootExpression;
    String embeddingViewExpression;
    boolean batchedIdValues = false;
    if (batchCorrelationMode == BatchCorrelationMode.VALUES) {
        correlationBasisEntityType = correlationBasisEntity;
        viewRootExpression = null;
        batchedIdValues = correlatesThis && correlationBasisEntity == null;
        embeddingViewExpression = correlatesThis ? CORRELATION_KEY_ALIAS : null;
    } else if (batchCorrelationMode == BatchCorrelationMode.VIEW_ROOTS) {
        correlationBasisEntityType = viewRootEntityClass;
        viewRootExpression = CORRELATION_KEY_ALIAS;
        embeddingViewExpression = null;
    } else {
        correlationBasisEntityType = embeddingViewEntityClass;
        viewRootExpression = null;
        embeddingViewExpression = CORRELATION_KEY_ALIAS;
    }
    this.criteriaBuilder = queryBuilder.getCriteriaBuilderFactory().create(queryBuilder.getEntityManager(), Object[].class);
    if (queryBuilder instanceof CTEBuilder<?>) {
        this.criteriaBuilder.withCtesFrom((CTEBuilder<?>) queryBuilder);
    }
    this.viewRootJpqlMacro = new CorrelatedSubqueryViewRootJpqlMacro(criteriaBuilder, optionalParameters, viewRootExpression != null, viewRootEntityClass, viewRootIdAttributePath, viewRootExpression);
    this.embeddingViewJpqlMacro = new CorrelatedSubqueryEmbeddingViewJpqlMacro(criteriaBuilder, optionalParameters, embeddingViewExpression != null, embeddingViewEntityClass, embeddingViewIdAttributePath, embeddingViewExpression, batchedIdValues, viewRootJpqlMacro);
    this.criteriaBuilder.registerMacro("view", new MutableViewJpqlMacro(correlationResult));
    this.criteriaBuilder.registerMacro("view_root", viewRootJpqlMacro);
    this.criteriaBuilder.registerMacro("embedding_view", embeddingViewJpqlMacro);
    String joinBase = CORRELATION_KEY_ALIAS;
    SubqueryCorrelationBuilder correlationBuilder = new SubqueryCorrelationBuilder(queryBuilder, optionalParameters, criteriaBuilder, correlationAlias, correlationExternalAlias, correlationResult, correlationBasisType, correlationBasisEntityType, joinBase, attributePath, batchSize, limiter, false);
    CorrelationProvider provider = correlationProviderFactory.create(entityViewConfiguration.getCriteriaBuilder(), entityViewConfiguration.getOptionalParameters());
    String correlationKeyExpression;
    if (batchSize > 1) {
        if (batchCorrelationMode == BatchCorrelationMode.VALUES) {
            this.correlationParamName = CORRELATION_KEY_ALIAS;
        // TODO: when using EMBEDDING_VIEW, we could make use of correlationBasis instead of binding parameters separately
        } else {
            this.correlationParamName = generateCorrelationParamName();
        }
        if (correlationBasisEntityType != null) {
            correlationKeyExpression = CORRELATION_KEY_ALIAS;
            if (batchCorrelationMode == BatchCorrelationMode.VALUES) {
                correlationSelectExpression = CORRELATION_KEY_ALIAS + '.' + getEntityIdName(correlationBasisEntityType);
            } else {
                correlationSelectExpression = CORRELATION_KEY_ALIAS + '.' + viewRootIdAttributePath;
            }
        } else {
            // The correlation key is basic type
            correlationSelectExpression = correlationKeyExpression = CORRELATION_KEY_ALIAS;
        }
    } else {
        this.correlationParamName = generateCorrelationParamName();
        this.correlationSelectExpression = correlationKeyExpression = null;
    }
    int originalFirstResult = criteriaBuilder.getFirstResult();
    int originalMaxResults = criteriaBuilder.getMaxResults();
    if (batchSize > 1 && batchCorrelationMode == BatchCorrelationMode.VALUES) {
        provider.applyCorrelation(correlationBuilder, correlationKeyExpression);
    } else {
        provider.applyCorrelation(correlationBuilder, ':' + correlationParamName);
    }
    if (batchSize > 1 && (originalFirstResult != criteriaBuilder.getFirstResult() || originalMaxResults != criteriaBuilder.getMaxResults())) {
        throw new IllegalArgumentException("Correlation provider '" + provider + "' wrongly uses setFirstResult() or setMaxResults() on the query builder which might lead to wrong results. Use SELECT fetching with batch size 1 or reformulate the correlation provider to use the limit/offset in a subquery!");
    }
    if (fetches.length != 0) {
        for (int i = 0; i < fetches.length; i++) {
            criteriaBuilder.fetch(fetches[i]);
        }
    }
    if (indexFetches.length != 0) {
        for (int i = 0; i < indexFetches.length; i++) {
            criteriaBuilder.fetch(indexFetches[i]);
        }
    }
    return correlationBuilder.getCorrelationRoot();
}
Also used : CorrelatedSubqueryViewRootJpqlMacro(com.blazebit.persistence.view.impl.macro.CorrelatedSubqueryViewRootJpqlMacro) MutableViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro) CorrelationProvider(com.blazebit.persistence.view.CorrelationProvider) CorrelatedSubqueryEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.CorrelatedSubqueryEmbeddingViewJpqlMacro) CTEBuilder(com.blazebit.persistence.CTEBuilder)

Example 3 with MutableViewJpqlMacro

use of com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro in project blaze-persistence by Blazebit.

the class AbstractCorrelatedSubselectTupleTransformer method prepare.

private void prepare() {
    JpaProvider jpaProvider = entityViewConfiguration.getCriteriaBuilder().getService(JpaProvider.class);
    FullQueryBuilder<?, ?> queryBuilder = entityViewConfiguration.getCriteriaBuilder();
    Map<String, Object> optionalParameters = entityViewConfiguration.getOptionalParameters();
    Class<?> correlationBasisEntityType = correlationBasisEntity;
    String viewRootExpression = viewRootAlias;
    EmbeddingViewJpqlMacro embeddingViewJpqlMacro = entityViewConfiguration.getEmbeddingViewJpqlMacro();
    ViewJpqlMacro viewJpqlMacro = entityViewConfiguration.getViewJpqlMacro();
    if (queryBuilder instanceof PaginatedCriteriaBuilder<?>) {
        criteriaBuilder = queryBuilder.copyCriteriaBuilder(Object[].class, false);
    } else {
        LimitBuilder<?> limitBuilder = (LimitBuilder<?>) queryBuilder;
        // To set the limit, we need the JPA provider to support this
        if (jpaProvider.supportsSubqueryInFunction() && (limitBuilder.getFirstResult() > 0 || limitBuilder.getMaxResults() < Integer.MAX_VALUE)) {
            // we must turn this query builder into a paginated criteria builder first
            try {
                criteriaBuilder = queryBuilder.copyCriteriaBuilder(Object[].class, true).page(limitBuilder.getFirstResult(), limitBuilder.getMaxResults()).copyCriteriaBuilder(Object[].class, false);
            } catch (IllegalStateException ex) {
                LOG.log(Level.WARNING, "Could not create a paginated criteria builder for SUBSELECT fetching which might lead to bad performance", ex);
                criteriaBuilder = queryBuilder.copyCriteriaBuilder(Object[].class, false);
            }
        } else {
            // Regular query without limit/offset
            criteriaBuilder = queryBuilder.copyCriteriaBuilder(Object[].class, false);
        }
    }
    int originalFirstResult = 0;
    int originalMaxResults = Integer.MAX_VALUE;
    // A copied query that is extended with further joins can't possibly use the limits provided by the outer query
    ((LimitBuilder<?>) criteriaBuilder).setFirstResult(originalFirstResult);
    ((LimitBuilder<?>) criteriaBuilder).setMaxResults(originalMaxResults);
    this.viewRootJpqlMacro = new CorrelatedSubqueryViewRootJpqlMacro(criteriaBuilder, optionalParameters, false, viewRootEntityClass, idAttributePath, viewRootExpression);
    criteriaBuilder.registerMacro("view", viewJpqlMacro);
    criteriaBuilder.registerMacro("view_root", viewRootJpqlMacro);
    criteriaBuilder.registerMacro("embedding_view", embeddingViewJpqlMacro);
    String oldViewPath = viewJpqlMacro.getViewPath();
    String oldEmbeddingViewPath = embeddingViewJpqlMacro.getEmbeddingViewPath();
    viewJpqlMacro.setViewPath(correlationResultExpression);
    embeddingViewJpqlMacro.setEmbeddingViewPath(embeddingViewPath);
    String joinBase = embeddingViewPath;
    SubqueryCorrelationBuilder correlationBuilder = new SubqueryCorrelationBuilder(queryBuilder, optionalParameters, criteriaBuilder, correlationAlias, correlationExternalAlias, correlationResultExpression, correlationBasisType, correlationBasisEntityType, joinBase, attributePath, 1, limiter, true);
    CorrelationProvider provider = correlationProviderFactory.create(entityViewConfiguration.getCriteriaBuilder(), entityViewConfiguration.getOptionalParameters());
    provider.applyCorrelation(correlationBuilder, correlationBasisExpression);
    if (criteriaBuilder instanceof LimitBuilder<?>) {
        if (originalFirstResult != ((LimitBuilder<?>) criteriaBuilder).getFirstResult() || originalMaxResults != ((LimitBuilder<?>) criteriaBuilder).getMaxResults()) {
            throw new IllegalArgumentException("Correlation provider '" + provider + "' wrongly uses setFirstResult() or setMaxResults() on the query builder which might lead to wrong results. Use SELECT fetching with batch size 1 or reformulate the correlation provider to use the limit/offset in a subquery!");
        }
    }
    if (fetches.length != 0) {
        for (int i = 0; i < fetches.length; i++) {
            criteriaBuilder.fetch(fetches[i]);
        }
    }
    if (indexFetches.length != 0) {
        for (int i = 0; i < indexFetches.length; i++) {
            criteriaBuilder.fetch(indexFetches[i]);
        }
    }
    // Before we can determine whether we use view roots or embedding views, we need to add all selects, otherwise macros might report false although they are used
    final String correlationRoot = correlationBuilder.getCorrelationRoot();
    final int tupleSuffix = maximumViewMapperCount + 1 + (indexCorrelator == null && indexExpression == null ? 0 : 1);
    ObjectBuilder<Object[]> objectBuilder = (ObjectBuilder<Object[]>) correlator.finish(criteriaBuilder, entityViewConfiguration, 0, tupleSuffix, correlationRoot, embeddingViewJpqlMacro, true);
    final boolean usesViewRoot = viewRootJpqlMacro.usesViewMacro();
    final boolean usesEmbeddingView = embeddingViewJpqlMacro.usesEmbeddingView();
    if (usesEmbeddingView && !(embeddingViewType instanceof ViewType<?>)) {
        throw new IllegalStateException("The use of EMBEDDING_VIEW in the correlation for '" + embeddingViewType.getJavaType().getName() + "." + attributePath.substring(attributePath.lastIndexOf('.') + 1) + "' is illegal because the embedding view type '" + embeddingViewType.getJavaType().getName() + "' does not declare a @IdMapping!");
    } else if (usesViewRoot && !(viewRootType instanceof ViewType<?>)) {
        throw new IllegalStateException("The use of VIEW_ROOT in the correlation for '" + embeddingViewType.getJavaType().getName() + "." + attributePath.substring(attributePath.lastIndexOf('.') + 1) + "' is illegal because the view root type '" + viewRootType.getJavaType().getName() + "' does not declare a @IdMapping!");
    }
    final int maximumSlotsFilled;
    final int elementKeyIndex;
    final int elementViewIndex;
    if (usesEmbeddingView) {
        maximumSlotsFilled = embeddingViewIdMapperCount == 0 ? 1 : embeddingViewIdMapperCount;
        elementKeyIndex = (maximumViewMapperCount - maximumSlotsFilled) + 2 + valueIndex;
        elementViewIndex = (maximumViewMapperCount - maximumSlotsFilled) + 1 + valueIndex;
        viewIndex = embeddingViewIndex;
    } else if (usesViewRoot) {
        maximumSlotsFilled = viewRootIdMapperCount == 0 ? 1 : viewRootIdMapperCount;
        elementKeyIndex = (maximumViewMapperCount - maximumSlotsFilled) + 2 + valueIndex;
        elementViewIndex = (maximumViewMapperCount - maximumSlotsFilled) + 1 + valueIndex;
        viewIndex = viewRootIndex;
    } else {
        maximumSlotsFilled = 0;
        elementKeyIndex = maximumViewMapperCount + 1 + valueIndex;
        elementViewIndex = 1 + valueIndex;
        viewIndex = -1;
    }
    for (int i = maximumSlotsFilled; i < maximumViewMapperCount; i++) {
        criteriaBuilder.select("NULL");
    }
    ExpressionFactory ef = criteriaBuilder.getService(ExpressionFactory.class);
    if (usesEmbeddingView) {
        EntityViewConfiguration configuration = new EntityViewConfiguration(criteriaBuilder, ef, new MutableViewJpqlMacro(), new MutableEmbeddingViewJpqlMacro(), Collections.<String, Object>emptyMap(), Collections.<String, Object>emptyMap(), entityViewConfiguration.getFetches(), attributePath);
        ObjectBuilder<Object[]> embeddingViewObjectBuilder = createViewAwareObjectBuilder(criteriaBuilder, embeddingViewType, configuration, embeddingViewIdExpression);
        if (embeddingViewObjectBuilder == null) {
            criteriaBuilder.select(embeddingViewIdExpression);
        } else {
            criteriaBuilder.selectNew(objectBuilder = new LateAdditionalObjectBuilder(objectBuilder, embeddingViewObjectBuilder, true));
        }
    } else if (usesViewRoot) {
        EntityViewConfiguration configuration = new EntityViewConfiguration(criteriaBuilder, ef, new MutableViewJpqlMacro(), new MutableEmbeddingViewJpqlMacro(), Collections.<String, Object>emptyMap(), Collections.<String, Object>emptyMap(), entityViewConfiguration.getFetches(), attributePath);
        ObjectBuilder<Object[]> viewRootObjectBuilder = createViewAwareObjectBuilder(criteriaBuilder, viewRootType, configuration, viewRootIdExpression);
        if (viewRootObjectBuilder == null) {
            criteriaBuilder.select(viewRootIdExpression);
        } else {
            criteriaBuilder.selectNew(objectBuilder = new LateAdditionalObjectBuilder(objectBuilder, viewRootObjectBuilder, true));
        }
    }
    criteriaBuilder.select(correlationKeyExpression);
    if (indexCorrelator != null) {
        ObjectBuilder<?> indexBuilder = indexCorrelator.finish(criteriaBuilder, entityViewConfiguration, maximumViewMapperCount + 2, 0, indexExpression, embeddingViewJpqlMacro, true);
        if (indexBuilder != null) {
            criteriaBuilder.selectNew(new LateAdditionalObjectBuilder(objectBuilder, indexBuilder, false));
        }
    }
    populateParameters(entityViewConfiguration, criteriaBuilder);
    viewJpqlMacro.setViewPath(oldViewPath);
    embeddingViewJpqlMacro.setEmbeddingViewPath(oldEmbeddingViewPath);
    List<Object[]> resultList = (List<Object[]>) criteriaBuilder.getResultList();
    Map<Object, Map<Object, Object>> collections = new HashMap<>(resultList.size());
    for (int i = 0; i < resultList.size(); i++) {
        Object[] element = resultList.get(i);
        Map<Object, Object> viewRootResult = collections.get(element[elementViewIndex]);
        if (viewRootResult == null) {
            viewRootResult = new HashMap<>();
            collections.put(element[elementViewIndex], viewRootResult);
        }
        if (this.containerAccumulator == null) {
            viewRootResult.put(element[elementKeyIndex], element[valueIndex]);
        } else {
            Object result = viewRootResult.get(element[elementKeyIndex]);
            if (result == null) {
                result = createDefaultResult();
                viewRootResult.put(element[elementKeyIndex], result);
            }
            Object indexObject = null;
            if (indexCorrelator != null || indexExpression != null) {
                indexObject = element[elementKeyIndex + 1];
            }
            this.containerAccumulator.add(result, indexObject, element[valueIndex], isRecording());
        }
    }
    this.collections = collections;
}
Also used : EntityViewConfiguration(com.blazebit.persistence.view.impl.EntityViewConfiguration) LateAdditionalObjectBuilder(com.blazebit.persistence.view.impl.objectbuilder.LateAdditionalObjectBuilder) HashMap(java.util.HashMap) ViewJpqlMacro(com.blazebit.persistence.view.spi.ViewJpqlMacro) EmbeddingViewJpqlMacro(com.blazebit.persistence.view.spi.EmbeddingViewJpqlMacro) MutableViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro) MutableEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro) PaginatedCriteriaBuilder(com.blazebit.persistence.PaginatedCriteriaBuilder) MutableEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro) List(java.util.List) ExpressionFactory(com.blazebit.persistence.parser.expression.ExpressionFactory) JpaProvider(com.blazebit.persistence.spi.JpaProvider) LimitBuilder(com.blazebit.persistence.LimitBuilder) CorrelatedSubqueryViewRootJpqlMacro(com.blazebit.persistence.view.impl.macro.CorrelatedSubqueryViewRootJpqlMacro) EmbeddingViewJpqlMacro(com.blazebit.persistence.view.spi.EmbeddingViewJpqlMacro) MutableEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro) ObjectBuilder(com.blazebit.persistence.ObjectBuilder) LateAdditionalObjectBuilder(com.blazebit.persistence.view.impl.objectbuilder.LateAdditionalObjectBuilder) MutableViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro) CorrelationProvider(com.blazebit.persistence.view.CorrelationProvider) HashMap(java.util.HashMap) Map(java.util.Map) UpdatableViewMap(com.blazebit.persistence.view.impl.objectbuilder.transformator.UpdatableViewMap) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Example 4 with MutableViewJpqlMacro

use of com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro in project blaze-persistence by Blazebit.

the class MetamodelBuildingContextImpl method createMacroAwareExpressionFactory.

@Override
public MacroConfigurationExpressionFactory createMacroAwareExpressionFactory(String viewRoot) {
    MacroConfiguration originalMacroConfiguration = expressionFactory.getDefaultMacroConfiguration();
    ExpressionFactory cachingExpressionFactory = expressionFactory.unwrap(AbstractCachingExpressionFactory.class);
    Map<String, MacroFunction> macros = new HashMap<>();
    macros.put("view", new JpqlMacroAdapter(new MutableViewJpqlMacro(viewRoot), cachingExpressionFactory));
    macros.put("view_root", new JpqlMacroAdapter(new DefaultViewRootJpqlMacro(viewRoot), cachingExpressionFactory));
    macros.put("embedding_view", new JpqlMacroAdapter(new MutableEmbeddingViewJpqlMacro(), cachingExpressionFactory));
    MacroConfiguration macroConfiguration = originalMacroConfiguration.with(macros);
    return new MacroConfigurationExpressionFactory(cachingExpressionFactory, macroConfiguration);
}
Also used : MacroFunction(com.blazebit.persistence.parser.expression.MacroFunction) MacroConfiguration(com.blazebit.persistence.parser.expression.MacroConfiguration) AbstractCachingExpressionFactory(com.blazebit.persistence.parser.expression.AbstractCachingExpressionFactory) ExpressionFactory(com.blazebit.persistence.parser.expression.ExpressionFactory) MacroConfigurationExpressionFactory(com.blazebit.persistence.view.impl.MacroConfigurationExpressionFactory) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) MutableEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro) JpqlMacroAdapter(com.blazebit.persistence.view.impl.JpqlMacroAdapter) DefaultViewRootJpqlMacro(com.blazebit.persistence.view.impl.macro.DefaultViewRootJpqlMacro) MutableViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro) MacroConfigurationExpressionFactory(com.blazebit.persistence.view.impl.MacroConfigurationExpressionFactory)

Example 5 with MutableViewJpqlMacro

use of com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro in project blaze-persistence by Blazebit.

the class EntityViewSettingHelper method apply.

@SuppressWarnings("unchecked")
public static <T, Q extends FullQueryBuilder<T, Q>> Q apply(EntityViewSetting<T, Q> setting, EntityViewManagerImpl evm, CriteriaBuilder<?> criteriaBuilder, String entityViewRoot) {
    ManagedViewTypeImplementor<?> managedView = evm.getMetamodel().managedView(setting.getEntityViewClass());
    if (managedView == null) {
        throw new IllegalArgumentException("There is no entity view for the class '" + setting.getEntityViewClass().getName() + "' registered!");
    }
    MappingConstructorImpl<?> mappingConstructor = (MappingConstructorImpl<?>) managedView.getConstructor(setting.getViewConstructorName());
    if (managedView instanceof FlatViewType<?>) {
        if (managedView.hasJoinFetchedCollections()) {
            throw new IllegalArgumentException("Can't use the flat view '" + managedView.getJavaType().getName() + "' as view root because it contains join fetched collections! " + "Consider adding a @IdMapping to the entity view or use a different fetch strategy for the collections!");
        }
        if (mappingConstructor == null) {
            if (managedView.getConstructors().size() > 1) {
                mappingConstructor = (MappingConstructorImpl<T>) managedView.getConstructor("init");
            } else if (managedView.getConstructors().size() == 1) {
                mappingConstructor = (MappingConstructorImpl<T>) managedView.getConstructors().toArray()[0];
            }
        }
        if (mappingConstructor != null && mappingConstructor.hasJoinFetchedCollections()) {
            throw new IllegalArgumentException("Can't use the flat view '" + managedView.getJavaType().getName() + "' with the mapping constructor '" + mappingConstructor.getName() + "' as view root because it contains join fetched collections! " + "Consider adding a @IdMapping to the entity view or use a different fetch strategy for the collections!");
        }
    }
    if (managedView.isUpdatable() && !setting.getFetches().isEmpty()) {
        throw new IllegalArgumentException("Specifying fetches for @UpdatableEntityViews is currently disallowed. Remove the fetches!");
    }
    ExpressionFactory ef = criteriaBuilder.getService(ExpressionFactory.class);
    Map<String, Object> optionalParameters;
    if (setting.getOptionalParameters().isEmpty()) {
        optionalParameters = evm.getOptionalParameters();
    } else {
        optionalParameters = new HashMap<>(evm.getOptionalParameters());
        optionalParameters.putAll(setting.getOptionalParameters());
        optionalParameters = Collections.unmodifiableMap(optionalParameters);
    }
    Collection<String> requestedFetches;
    if (setting.getFetches().isEmpty() || !setting.hasAttributeFilters() && !setting.hasAttributeSorters()) {
        requestedFetches = setting.getFetches();
    } else {
        requestedFetches = new HashSet<>(setting.getFetches());
        addFetchesForNonMappingAttributes(setting.getAttributeFilterActivations().keySet(), managedView, requestedFetches);
        addFetchesForNonMappingAttributes(setting.getAttributeSorters().keySet(), managedView, requestedFetches);
    }
    Path root = criteriaBuilder.getPath(entityViewRoot);
    entityViewRoot = root.getPath();
    Q queryBuilder = getQueryBuilder(setting, criteriaBuilder, entityViewRoot, managedView, setting.getProperties());
    EntityViewConfiguration configuration = new EntityViewConfiguration(queryBuilder, ef, new MutableViewJpqlMacro(), new MutableEmbeddingViewJpqlMacro(), optionalParameters, setting.getProperties(), requestedFetches, managedView);
    queryBuilder.selectNew(evm.createObjectBuilder(managedView, mappingConstructor, root.getJavaType(), entityViewRoot, null, criteriaBuilder, configuration, 0, 0, false));
    Set<String> fetches = configuration.getFetches();
    applyAttributeFilters(setting, evm, queryBuilder, entityViewRoot, fetches, managedView);
    applyViewFilters(setting, evm, queryBuilder, managedView);
    applyAttributeSorters(setting, queryBuilder, entityViewRoot, fetches, managedView);
    applyOptionalParameters(optionalParameters, queryBuilder);
    return queryBuilder;
}
Also used : Path(com.blazebit.persistence.Path) ExpressionFactory(com.blazebit.persistence.parser.expression.ExpressionFactory) MutableViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro) MutableEmbeddingViewJpqlMacro(com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro) MappingConstructorImpl(com.blazebit.persistence.view.impl.metamodel.MappingConstructorImpl) FlatViewType(com.blazebit.persistence.view.metamodel.FlatViewType)

Aggregations

MutableViewJpqlMacro (com.blazebit.persistence.view.impl.macro.MutableViewJpqlMacro)6 ExpressionFactory (com.blazebit.persistence.parser.expression.ExpressionFactory)5 MutableEmbeddingViewJpqlMacro (com.blazebit.persistence.view.impl.macro.MutableEmbeddingViewJpqlMacro)5 MacroConfigurationExpressionFactory (com.blazebit.persistence.view.impl.MacroConfigurationExpressionFactory)3 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)3 ViewType (com.blazebit.persistence.view.metamodel.ViewType)3 HashMap (java.util.HashMap)3 CorrelationProvider (com.blazebit.persistence.view.CorrelationProvider)2 AttributeAccessor (com.blazebit.persistence.view.impl.accessor.AttributeAccessor)2 EntityTupleizer (com.blazebit.persistence.view.impl.entity.EntityTupleizer)2 CorrelatedSubqueryViewRootJpqlMacro (com.blazebit.persistence.view.impl.macro.CorrelatedSubqueryViewRootJpqlMacro)2 ManagedViewTypeImplementor (com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor)2 DefaultEntityTupleizer (com.blazebit.persistence.view.impl.update.DefaultEntityTupleizer)2 MappingAttribute (com.blazebit.persistence.view.metamodel.MappingAttribute)2 SingularAttribute (com.blazebit.persistence.view.metamodel.SingularAttribute)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 CTEBuilder (com.blazebit.persistence.CTEBuilder)1 LimitBuilder (com.blazebit.persistence.LimitBuilder)1 ObjectBuilder (com.blazebit.persistence.ObjectBuilder)1