use of com.blazebit.persistence.view.impl.objectbuilder.mapper.MultisetTupleElementMapper 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;
}
Aggregations