Search in sources :

Example 1 with AttributeAccessor

use of com.blazebit.persistence.view.impl.accessor.AttributeAccessor in project blaze-persistence by Blazebit.

the class ViewMapper method createAccessor.

private ObjectMapper createAccessor(ManagedViewType<S> sourceType, ManagedViewType<T> targetType, boolean ignoreMissing, EntityViewKindMapping entityViewKindMapping, EntityViewManager entityViewManager, ProxyFactory proxyFactory, MethodAttribute<? super T, ?> targetAttribute, String prefix, Map<String, Key<Object, Object>> subMappers) {
    String newPrefix;
    if (prefix.isEmpty()) {
        newPrefix = targetAttribute.getName();
    } else {
        newPrefix = prefix + "." + targetAttribute.getName();
    }
    Type<?> attributeType;
    MappingConstructorImpl<?> constructor = null;
    Boolean maybeMarkNew = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
    Key<Object, Object> subMapperKey = subMappers.get(newPrefix);
    if (subMapperKey == Key.EXCLUDE_MARKER) {
        return null;
    } else if (subMapperKey != null) {
        ignoreMissing = subMapperKey.ignoreMissing;
        maybeMarkNew = subMapperKey.markNew;
    }
    // Try to find a source attribute
    MethodAttribute<?, ?> sourceAttribute;
    AttributeAccessor accessor;
    if (sourceType == null) {
        sourceAttribute = null;
        if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
            return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
        }
        accessor = Accessors.forEntityMapping((EntityViewManagerImpl) entityViewManager, targetAttribute);
        if (accessor == null) {
            if (ignoreMissing) {
                return null;
            }
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", targetType);
        }
    } else {
        sourceAttribute = sourceType.getAttribute(targetAttribute.getName());
        if (sourceAttribute == null) {
            if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
                return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
            }
            // Optionally ignore missing attributes
            if (ignoreMissing) {
                return null;
            }
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", sourceType, targetType);
        }
        accessor = Accessors.forViewAttribute(null, sourceAttribute, true);
    }
    // Handle conversion from one type to another
    if (targetAttribute.isCollection()) {
        if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different plural type than in source type!", sourceType, targetType);
        }
        PluralAttribute<?, ?, ?> targetPluralAttr = (PluralAttribute<?, ?, ?>) targetAttribute;
        Type<?> elementType = (sourceAttribute == null) ? null : ((PluralAttribute<?, ?, ?>) sourceAttribute).getElementType();
        ViewMapper<Object, Object> valueMapper = null;
        attributeType = targetPluralAttr.getElementType();
        if (subMapperKey != null) {
            attributeType = subMapperKey.targetType;
            constructor = subMapperKey.targetConstructor;
        }
        if (targetAttribute.isSubview()) {
            valueMapper = createViewMapper(elementType, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
        } else if ((sourceType != null) && (targetPluralAttr.getElementType() != elementType)) {
            throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different element type than in source type!", sourceType, targetType);
        }
        boolean needsDirtyTracker = ((AbstractAttribute<?, ?>) targetAttribute).needsDirtyTracker();
        if (targetPluralAttr.getCollectionType() == PluralAttribute.CollectionType.MAP) {
            MapAttribute<?, ?, ?> targetMapAttr = (MapAttribute<?, ?, ?>) targetAttribute;
            Type<?> keyType = (sourceAttribute == null) ? null : ((MapAttribute<?, ?, ?>) sourceAttribute).getKeyType();
            ViewMapper<Object, Object> keyMapper = null;
            if (targetMapAttr.isKeySubview()) {
                String newKeyPrefix = "KEY(" + newPrefix + ")";
                Key<Object, Object> keySubMapperKey = subMappers.get(newKeyPrefix);
                if (keySubMapperKey == Key.EXCLUDE_MARKER) {
                    keyMapper = null;
                } else {
                    constructor = null;
                    Type<?> keyTargetType = targetMapAttr.getKeyType();
                    Boolean maybeMarkNewKey = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
                    if (subMapperKey != null) {
                        constructor = keySubMapperKey.targetConstructor;
                        keyTargetType = keySubMapperKey.targetType;
                        ignoreMissing = keySubMapperKey.ignoreMissing;
                        maybeMarkNewKey = keySubMapperKey.markNew;
                    }
                    keyMapper = createViewMapper(keyType, keyTargetType, constructor, ignoreMissing, maybeMarkNewKey, entityViewManager, proxyFactory, newPrefix, subMappers);
                }
            } else if ((sourceType != null) && (targetMapAttr.getKeyType() != keyType)) {
                throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different key type than in source type!", sourceType, targetType);
            }
            MapInstantiatorImplementor<?, ?> mapInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getMapInstantiator();
            return new MapObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, mapInstantiator, keyMapper, valueMapper);
        } else {
            CollectionInstantiatorImplementor<?, ?> collectionInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getCollectionInstantiator();
            return new CollectionObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, collectionInstantiator, valueMapper);
        }
    } else if (targetAttribute.isSubview()) {
        attributeType = ((SingularAttribute<?, ?>) targetAttribute).getType();
        if (subMapperKey != null) {
            attributeType = subMapperKey.targetType;
            constructor = subMapperKey.targetConstructor;
        }
        Type<?> type = (sourceAttribute == null) ? null : ((SingularAttribute<?, ?>) sourceAttribute).getType();
        ViewMapper<Object, Object> mapper = createViewMapper(type, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
        return new AttributeObjectMapper(accessor, mapper);
    } else if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
        throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different type than in source type!", sourceType, targetType);
    } else {
        return new PassthroughObjectMapper(accessor);
    }
}
Also used : AbstractAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractAttribute) EntityViewManagerImpl(com.blazebit.persistence.view.impl.EntityViewManagerImpl) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) SingularAttribute(com.blazebit.persistence.view.metamodel.SingularAttribute) Type(com.blazebit.persistence.view.metamodel.Type) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor)

Example 2 with AttributeAccessor

use of com.blazebit.persistence.view.impl.accessor.AttributeAccessor in project blaze-persistence by Blazebit.

the class Mappers method forViewToEntityAttributeMapping.

public static <S, T> Mapper<S, T> forViewToEntityAttributeMapping(EntityViewManagerImpl evm, ManagedViewType<S> sourceViewType, Class<T> targetEntityClass, Map<String, String> mapping) {
    EntityMetamodel metamodel = evm.getCriteriaBuilderFactory().getService(EntityMetamodel.class);
    List<AttributeAccessor> source = new ArrayList<>(mapping.size());
    List<AttributeAccessor> target = new ArrayList<>(mapping.size());
    for (Map.Entry<String, String> entry : mapping.entrySet()) {
        source.add(Accessors.forViewAttributePath(evm, sourceViewType, entry.getKey(), true));
        target.add(Accessors.forEntityMapping(evm, targetEntityClass, entry.getValue()));
    }
    return new AttributeMapper<>(source, target);
}
Also used : ArrayList(java.util.ArrayList) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor) EntityMetamodel(com.blazebit.persistence.parser.EntityMetamodel) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with AttributeAccessor

use of com.blazebit.persistence.view.impl.accessor.AttributeAccessor 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 4 with AttributeAccessor

use of com.blazebit.persistence.view.impl.accessor.AttributeAccessor in project blaze-persistence by Blazebit.

the class IndexedListAttributeFlusher method determineCollectionActions.

@Override
protected List<CollectionAction<Collection<?>>> determineCollectionActions(UpdateContext context, V initial, V current, EqualityChecker equalityChecker) {
    // We try to find a common prefix and from that on, we infer actions
    List<CollectionAction<Collection<?>>> actions = new ArrayList<>();
    int lastUnmatchedIndex = 0;
    if (initial != null && !initial.isEmpty()) {
        int initialSize = initial.size();
        if (elementDescriptor.isSubview() && elementDescriptor.isIdentifiable()) {
            final AttributeAccessor subviewIdAccessor = elementDescriptor.getViewToEntityMapper().getViewIdAccessor();
            for (int i = 0; i < initialSize; i++) {
                Object initialViewId = subviewIdAccessor.getValue(initial.get(i));
                if (i < current.size()) {
                    Object currentViewId = subviewIdAccessor.getValue(current.get(i));
                    if (!initialViewId.equals(currentViewId)) {
                        break;
                    } else {
                        lastUnmatchedIndex++;
                    }
                } else {
                    // remove all following elements and Keep the same index 'i'
                    if (i < initialSize) {
                        for (int j = i; j < initialSize - 1; j++) {
                            actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListRemoveAction<>(i, false, initial));
                        }
                        actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListRemoveAction<>(i, true, initial));
                    }
                    // Break since there are no more elements to check
                    lastUnmatchedIndex = initialSize;
                    break;
                }
            }
        } else {
            for (int i = 0; i < initialSize; i++) {
                Object initialElement = initial.get(i);
                if (i < current.size()) {
                    Object viewElement = current.get(i);
                    if (!equalityChecker.isEqual(context, initialElement, viewElement)) {
                        break;
                    } else {
                        lastUnmatchedIndex++;
                    }
                } else {
                    // remove all following elements and Keep the same index 'i'
                    if (i < initialSize) {
                        for (int j = i; j < initialSize - 1; j++) {
                            actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListRemoveAction<>(i, false, initial));
                        }
                        actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListRemoveAction<>(i, true, initial));
                    }
                    // Break since there are no more elements to check
                    lastUnmatchedIndex = initialSize;
                    break;
                }
            }
        }
        // Remove remaining elements in the list that couldn't be matched
        if (lastUnmatchedIndex < initialSize) {
            for (int i = lastUnmatchedIndex; i < initialSize - 1; i++) {
                actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListRemoveAction<>(lastUnmatchedIndex, false, initial));
            }
            actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListRemoveAction<>(lastUnmatchedIndex, true, initial));
        }
    }
    // Add new elements that are not matched
    if (lastUnmatchedIndex < current.size()) {
        for (int i = lastUnmatchedIndex; i < current.size(); i++) {
            actions.add((CollectionAction<Collection<?>>) (CollectionAction<?>) new ListAddAction<>(lastUnmatchedIndex, true, current.get(i)));
        }
    }
    return actions;
}
Also used : CollectionAction(com.blazebit.persistence.view.impl.collection.CollectionAction) ArrayList(java.util.ArrayList) RecordingCollection(com.blazebit.persistence.view.impl.collection.RecordingCollection) Collection(java.util.Collection) InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor)

Example 5 with AttributeAccessor

use of com.blazebit.persistence.view.impl.accessor.AttributeAccessor in project blaze-persistence by Blazebit.

the class InverseFlusher method forAttribute.

public static <E> InverseFlusher<E> forAttribute(EntityViewManagerImpl evm, Map<Object, EntityViewUpdaterImpl> localCache, ManagedViewType<?> viewType, AbstractMethodAttribute<?, ?> attribute, TypeDescriptor childTypeDescriptor, EntityViewUpdaterImpl owner, String ownerMapping) {
    if (attribute.getMappedBy() != null) {
        String attributeLocation = attribute.getLocation();
        Type<?> elementType = attribute instanceof PluralAttribute<?, ?, ?> ? ((PluralAttribute<?, ?, ?>) attribute).getElementType() : ((SingularAttribute<?, ?>) attribute).getType();
        Class<?> elementEntityClass = null;
        AttributeAccessor parentReferenceAttributeAccessor = null;
        Mapper<Object, Object> parentEntityOnChildViewMapper = null;
        Mapper<Object, Object> parentEntityOnChildEntityAddMapper = null;
        Mapper<Object, Object> parentEntityOnChildEntityRemoveMapper = null;
        TargetViewClassBasedInverseViewToEntityMapper childViewToEntityMapper = null;
        InverseEntityToEntityMapper childEntityToEntityMapper = null;
        ViewToEntityMapper parentReferenceViewToEntityMapper = new LoadOnlyViewToEntityMapper(new ReferenceEntityLoader(evm, viewType, EntityViewUpdaterImpl.createViewIdMapper(evm, localCache, viewType)), Accessors.forViewId(evm, (ViewType<?>) viewType, true), evm.getEntityIdAccessor());
        ViewToEntityMapper childReferenceViewToEntityMapper = null;
        TypeDescriptor parentReferenceTypeDescriptor = TypeDescriptor.forInverseAttribute(parentReferenceViewToEntityMapper);
        if (attribute.getWritableMappedByMappings() != null) {
            // This happens when the mapped by attribute is insertable=false and updatable=false
            if (childTypeDescriptor.isSubview()) {
                ViewType<?> childViewType = (ViewType<?>) elementType;
                elementEntityClass = childViewType.getEntityClass();
                Map<Class<?>, Mapper<Object, Object>> mappers = new HashMap<>();
                for (ManagedViewType<?> type : attribute.getViewTypes()) {
                    Mapper<Object, Object> mapper = Mappers.forViewConvertToViewAttributeMapping(evm, (ViewType<Object>) viewType, (ViewType<Object>) type, attribute.getWritableMappedByMappings(), (Mapper<Object, Object>) Mappers.forEntityAttributeMappingConvertToViewAttributeMapping(evm, viewType.getEntityClass(), type, attribute.getWritableMappedByMappings()));
                    if (mapper == null) {
                        mapper = NoopMapper.INSTANCE;
                    }
                    mappers.put(type.getJavaType(), mapper);
                }
                parentEntityOnChildViewMapper = (Mapper<Object, Object>) Mappers.targetViewClassBasedMapper(mappers);
                parentEntityOnChildEntityAddMapper = parentEntityOnChildEntityRemoveMapper = (Mapper<Object, Object>) Mappers.forEntityAttributeMapping(evm, viewType.getEntityClass(), childViewType.getEntityClass(), attribute.getWritableMappedByMappings());
                childReferenceViewToEntityMapper = new LoadOrPersistViewToEntityMapper(attributeLocation, evm, childViewType.getJavaType(), attribute.getReadOnlyAllowedSubtypes(), attribute.getPersistCascadeAllowedSubtypes(), attribute.getUpdateCascadeAllowedSubtypes(), new ReferenceEntityLoader(evm, childViewType, EntityViewUpdaterImpl.createViewIdMapper(evm, localCache, childViewType)), Accessors.forViewId(evm, childViewType, true), evm.getEntityIdAccessor(), true, owner, ownerMapping, localCache);
            } else if (childTypeDescriptor.isJpaEntity()) {
                Class<?> childType = elementType.getJavaType();
                elementEntityClass = childType;
                parentEntityOnChildViewMapper = (Mapper<Object, Object>) Mappers.forEntityAttributeMapping(evm, viewType.getEntityClass(), childType, attribute.getWritableMappedByMappings());
                parentEntityOnChildEntityAddMapper = parentEntityOnChildEntityRemoveMapper = (Mapper<Object, Object>) Mappers.forEntityAttributeMapping(evm, viewType.getEntityClass(), elementEntityClass, attribute.getWritableMappedByMappings());
            }
        } else {
            if (childTypeDescriptor.isSubview()) {
                ViewType<?> childViewType = (ViewType<?>) elementType;
                elementEntityClass = childViewType.getEntityClass();
                parentReferenceAttributeAccessor = Accessors.forEntityMapping(evm, childViewType.getEntityClass(), attribute.getMappedBy());
                childReferenceViewToEntityMapper = new LoadOrPersistViewToEntityMapper(attributeLocation, evm, childViewType.getJavaType(), attribute.getReadOnlyAllowedSubtypes(), attribute.getPersistCascadeAllowedSubtypes(), attribute.getUpdateCascadeAllowedSubtypes(), new ReferenceEntityLoader(evm, childViewType, EntityViewUpdaterImpl.createViewIdMapper(evm, localCache, childViewType)), Accessors.forViewId(evm, childViewType, true), evm.getEntityIdAccessor(), true, owner, ownerMapping, localCache);
                parentEntityOnChildEntityAddMapper = parentEntityOnChildEntityRemoveMapper = Mappers.forAccessor(parentReferenceAttributeAccessor);
                Map<Class<?>, Mapper<Object, Object>> mappers = new HashMap<>();
                for (ManagedViewType<?> type : attribute.getViewTypes()) {
                    Mapper<Object, Object> mapper = (Mapper<Object, Object>) Mappers.forViewConvertToViewAttributeMapping(evm, (ViewType<Object>) viewType, (ViewType<Object>) type, attribute.getMappedBy(), null);
                    if (mapper == null) {
                        mapper = NoopMapper.INSTANCE;
                    }
                    mappers.put(type.getJavaType(), mapper);
                }
                parentEntityOnChildViewMapper = (Mapper<Object, Object>) Mappers.targetViewClassBasedMapper(mappers);
            } else if (childTypeDescriptor.isJpaEntity()) {
                Class<?> childType = elementType.getJavaType();
                elementEntityClass = childType;
                parentReferenceAttributeAccessor = Accessors.forEntityMapping(evm, childType, attribute.getMappedBy());
                parentEntityOnChildEntityAddMapper = parentEntityOnChildEntityRemoveMapper = Mappers.forAccessor(parentReferenceAttributeAccessor);
                parentEntityOnChildViewMapper = Mappers.forAccessor(parentReferenceAttributeAccessor);
            }
        }
        DirtyAttributeFlusher<?, Object, ? extends Object> parentReferenceAttributeFlusher;
        ManagedType<?> managedType = evm.getMetamodel().getEntityMetamodel().getManagedType(elementEntityClass);
        Attribute<?, ?> inverseAttribute = JpaMetamodelUtils.getAttribute(managedType, attribute.getMappedBy());
        // Many-To-Many relation can't be handled by the inverse flushers
        if (inverseAttribute != null && inverseAttribute.isCollection()) {
            // A collection can only have a single attribute, so it's safe to assume a SimpleMapper
            parentEntityOnChildEntityAddMapper = new CollectionAddMapper<>(parentEntityOnChildEntityAddMapper == null ? parentReferenceAttributeAccessor : ((SimpleMapper<Object, Object>) parentEntityOnChildEntityAddMapper).getAttributeAccessor());
            parentEntityOnChildEntityRemoveMapper = new CollectionRemoveMapper<>(parentEntityOnChildEntityRemoveMapper == null ? parentReferenceAttributeAccessor : ((SimpleMapper<Object, Object>) parentEntityOnChildEntityRemoveMapper).getAttributeAccessor());
            parentReferenceAttributeFlusher = new ParentCollectionReferenceAttributeFlusher<>(attributeLocation, attribute.getMappedBy(), viewType.getFlushStrategy(), parentReferenceAttributeAccessor, null, null, null, TypeDescriptor.forInverseCollectionAttribute(viewType.getEntityClass(), new EntityBasicUserType(evm.getJpaProvider())));
        } else {
            parentEntityOnChildEntityRemoveMapper = new NullMapper<>(parentEntityOnChildEntityRemoveMapper);
            parentReferenceAttributeFlusher = new ParentReferenceAttributeFlusher<>(evm, viewType.getEntityClass(), attributeLocation, attribute.getMappedBy(), attribute.getWritableMappedByMappings(), parentReferenceTypeDescriptor, parentReferenceAttributeAccessor, parentEntityOnChildViewMapper);
        }
        UnmappedAttributeCascadeDeleter deleter = null;
        String parentIdAttributeName = null;
        String childIdAttributeName = null;
        Class<?> childIdViewClass = null;
        // Only construct when orphanRemoval or delete cascading is enabled, orphanRemoval implies delete cascading
        if (attribute.isDeleteCascaded()) {
            EntityMetamodel entityMetamodel = evm.getMetamodel().getEntityMetamodel();
            ExtendedManagedType<?> ownerManagedType = entityMetamodel.getManagedType(ExtendedManagedType.class, viewType.getEntityClass());
            ExtendedManagedType<?> elementManagedType = entityMetamodel.getManagedType(ExtendedManagedType.class, elementEntityClass);
            parentIdAttributeName = ownerManagedType.getIdAttribute().getName();
            childIdAttributeName = elementManagedType.getIdAttribute().getName();
            String mapping = attribute.getMappedBy();
            if (mapping != null) {
                if (mapping.isEmpty()) {
                    deleter = new UnmappedWritableBasicAttributeSetNullCascadeDeleter(evm, ownerManagedType.getType(), elementManagedType, attribute.getWritableMappedByMappings());
                } else {
                    ExtendedAttribute extendedAttribute = elementManagedType.getAttribute(mapping);
                    if (childTypeDescriptor.isSubview()) {
                        if (elementType instanceof ViewType<?>) {
                            MethodAttribute<?, ?> idAttribute = ((ViewType<?>) elementType).getIdAttribute();
                            if (idAttribute.isSubview()) {
                                // in this case, we need to fetch the id as view as the deleter expects it this way
                                childIdViewClass = idAttribute.getJavaType();
                            }
                        }
                        deleter = new ViewTypeCascadeDeleter(childTypeDescriptor.getViewToEntityMapper());
                    } else if (childTypeDescriptor.isJpaEntity()) {
                        deleter = new UnmappedBasicAttributeCascadeDeleter(evm, mapping, extendedAttribute, mapping + "." + parentIdAttributeName, false);
                    }
                }
            }
        }
        if (childTypeDescriptor.isSubview()) {
            InverseViewToEntityMapper<?> first = null;
            Map<Class<?>, InverseViewToEntityMapper<?>> mappers = new HashMap<>();
            for (ManagedViewType<?> type : attribute.getViewTypes()) {
                InverseViewToEntityMapper inverseViewToEntityMapper = new InverseViewToEntityMapper(evm, localCache, (ViewType<?>) type, parentEntityOnChildViewMapper, parentEntityOnChildEntityAddMapper, parentEntityOnChildEntityRemoveMapper, childTypeDescriptor.getViewToEntityMapper(), parentReferenceAttributeFlusher, EntityViewUpdaterImpl.createIdFlusher(evm, localCache, (ViewType<?>) type, EntityViewUpdaterImpl.createViewIdMapper(evm, localCache, type)));
                mappers.put(type.getJavaType(), inverseViewToEntityMapper);
                if (type == elementType) {
                    first = inverseViewToEntityMapper;
                }
            }
            childViewToEntityMapper = new TargetViewClassBasedInverseViewToEntityMapper(first, mappers);
        } else if (childTypeDescriptor.isJpaEntity()) {
            Class<?> childType = elementType.getJavaType();
            childEntityToEntityMapper = new InverseEntityToEntityMapper(evm, evm.getMetamodel().getEntityMetamodel().entity(childType), parentEntityOnChildEntityAddMapper, parentEntityOnChildEntityRemoveMapper, parentReferenceAttributeFlusher);
        }
        return new InverseFlusher(viewType.getEntityClass(), attribute.getMapping(), parentIdAttributeName, childIdAttributeName, childIdViewClass, deleter, parentReferenceViewToEntityMapper, parentReferenceAttributeFlusher, parentEntityOnChildViewMapper, childViewToEntityMapper, childReferenceViewToEntityMapper, parentEntityOnChildEntityAddMapper, childEntityToEntityMapper);
    }
    return null;
}
Also used : LoadOrPersistViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper) LoadOnlyViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper) HashMap(java.util.HashMap) CollectionRemoveMapper(com.blazebit.persistence.view.impl.mapper.CollectionRemoveMapper) LoadOrPersistViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper) LoadOnlyViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper) NoopMapper(com.blazebit.persistence.view.impl.mapper.NoopMapper) InverseEntityToEntityMapper(com.blazebit.persistence.view.impl.entity.InverseEntityToEntityMapper) NullMapper(com.blazebit.persistence.view.impl.mapper.NullMapper) CollectionAddMapper(com.blazebit.persistence.view.impl.mapper.CollectionAddMapper) TargetViewClassBasedInverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.TargetViewClassBasedInverseViewToEntityMapper) InverseElementToEntityMapper(com.blazebit.persistence.view.impl.entity.InverseElementToEntityMapper) Mapper(com.blazebit.persistence.view.impl.mapper.Mapper) SimpleMapper(com.blazebit.persistence.view.impl.mapper.SimpleMapper) ViewToEntityMapper(com.blazebit.persistence.view.impl.entity.ViewToEntityMapper) InverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.InverseViewToEntityMapper) LoadOrPersistViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper) LoadOnlyViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper) TargetViewClassBasedInverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.TargetViewClassBasedInverseViewToEntityMapper) ViewToEntityMapper(com.blazebit.persistence.view.impl.entity.ViewToEntityMapper) InverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.InverseViewToEntityMapper) TargetViewClassBasedInverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.TargetViewClassBasedInverseViewToEntityMapper) TargetViewClassBasedInverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.TargetViewClassBasedInverseViewToEntityMapper) InverseViewToEntityMapper(com.blazebit.persistence.view.impl.entity.InverseViewToEntityMapper) ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ReferenceEntityLoader(com.blazebit.persistence.view.impl.entity.ReferenceEntityLoader) InverseEntityToEntityMapper(com.blazebit.persistence.view.impl.entity.InverseEntityToEntityMapper) EntityBasicUserType(com.blazebit.persistence.view.impl.type.EntityBasicUserType) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor) EntityMetamodel(com.blazebit.persistence.parser.EntityMetamodel) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType)

Aggregations

AttributeAccessor (com.blazebit.persistence.view.impl.accessor.AttributeAccessor)22 InitialValueAttributeAccessor (com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor)14 HashMap (java.util.HashMap)11 ArrayList (java.util.ArrayList)9 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)8 ViewType (com.blazebit.persistence.view.metamodel.ViewType)8 Map (java.util.Map)8 LoadOrPersistViewToEntityMapper (com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper)6 MapAttribute (com.blazebit.persistence.view.metamodel.MapAttribute)6 MappingAttribute (com.blazebit.persistence.view.metamodel.MappingAttribute)6 PluralAttribute (com.blazebit.persistence.view.metamodel.PluralAttribute)6 EntityMetamodel (com.blazebit.persistence.parser.EntityMetamodel)5 ExtendedAttribute (com.blazebit.persistence.spi.ExtendedAttribute)5 EmbeddableUpdaterBasedViewToEntityMapper (com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper)5 ExtendedManagedType (com.blazebit.persistence.spi.ExtendedManagedType)4 PassthroughAttributeAccessor (com.blazebit.persistence.view.impl.accessor.PassthroughAttributeAccessor)4 ViewToEntityMapper (com.blazebit.persistence.view.impl.entity.ViewToEntityMapper)4 ManagedViewTypeImplementor (com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor)4 IdentityHashMap (java.util.IdentityHashMap)4 LinkedHashMap (java.util.LinkedHashMap)4