Search in sources :

Example 1 with LoadOnlyViewToEntityMapper

use of com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper 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)

Example 2 with LoadOnlyViewToEntityMapper

use of com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper in project blaze-persistence by Blazebit.

the class EntityViewUpdaterImpl method createSingularAttributeFlusher.

private DirtyAttributeFlusher<?, ?, ?> createSingularAttributeFlusher(EntityViewManagerImpl evm, Map<Object, EntityViewUpdaterImpl> localCache, ManagedViewTypeImplementor<?> viewType, AbstractMethodAttribute<?, ?> attribute, EntityViewUpdaterImpl owner, String ownerMapping) {
    EntityMetamodel entityMetamodel = evm.getMetamodel().getEntityMetamodel();
    Class<?> entityClass = viewType.getEntityClass();
    String attributeName = attribute.getName();
    String attributeMapping = attribute.getMapping();
    AttributeAccessor entityAttributeAccessor = Accessors.forEntityMapping(evm, attribute);
    String attributeLocation = attribute.getLocation();
    boolean cascadePersist = attribute.isPersistCascaded();
    boolean cascadeUpdate = attribute.isUpdateCascaded();
    boolean cascadeDelete = attribute.isDeleteCascaded();
    boolean viewOnlyDeleteCascaded = cascadeDelete && !entityMetamodel.getManagedType(ExtendedManagedType.class, entityClass).getAttribute(attributeMapping).isDeleteCascaded();
    boolean optimisticLockProtected = attribute.isOptimisticLockProtected();
    Set<Type<?>> readOnlyAllowedSubtypes = attribute.getReadOnlyAllowedSubtypes();
    Set<Type<?>> persistAllowedSubtypes = attribute.getPersistCascadeAllowedSubtypes();
    Set<Type<?>> updateAllowedSubtypes = attribute.getUpdateCascadeAllowedSubtypes();
    JpaProvider jpaProvider = evm.getJpaProvider();
    if (attribute.isSubview()) {
        boolean shouldFlushUpdates = cascadeUpdate && !updateAllowedSubtypes.isEmpty();
        boolean shouldFlushPersists = cascadePersist && !persistAllowedSubtypes.isEmpty();
        ManagedViewTypeImplementor<?> subviewType = (ManagedViewTypeImplementor<?>) ((com.blazebit.persistence.view.metamodel.SingularAttribute<?, ?>) attribute).getType();
        boolean passThrough = false;
        if (attribute.isUpdatable() || shouldFlushUpdates || (passThrough = shouldPassThrough(evm, viewType, attribute))) {
            // TODO: shouldn't this be done for any flat view? or are updatable flat views for entity types disallowed?
            if (!(subviewType.getJpaManagedType() instanceof EntityType<?>)) {
                AttributeAccessor viewAttributeAccessor = Accessors.forViewAttribute(evm, attribute, true);
                // A singular attribute where the subview refers to an embeddable type
                EmbeddableUpdaterBasedViewToEntityMapper viewToEntityMapper = new EmbeddableUpdaterBasedViewToEntityMapper(attributeLocation, evm, subviewType.getJavaType(), readOnlyAllowedSubtypes, persistAllowedSubtypes, updateAllowedSubtypes, EntityLoaders.referenceLoaderForAttribute(evm, localCache, subviewType, attribute), shouldFlushPersists, null, owner == null ? this : owner, ownerMapping == null ? attributeMapping : ownerMapping + "." + attributeMapping, localCache);
                CompositeAttributeFlusher nestedFlusher = (CompositeAttributeFlusher) viewToEntityMapper.getFullGraphNode();
                boolean supportsQueryFlush = nestedFlusher.supportsQueryFlush() && jpaProvider.supportsUpdateSetEmbeddable();
                String parameterName;
                String updateFragment;
                if (supportsQueryFlush) {
                    parameterName = attributeName;
                    updateFragment = attributeMapping;
                } else {
                    parameterName = attributeName + "_";
                    updateFragment = attributeMapping + ".";
                }
                return new EmbeddableAttributeFlusher<>(attributeName, attributeMapping, updateFragment, parameterName, optimisticLockProtected, passThrough, supportsQueryFlush, entityAttributeAccessor, viewAttributeAccessor, viewToEntityMapper);
            } else {
                // Subview refers to entity type
                ViewTypeImplementor<?> attributeViewType = (ViewTypeImplementor<?>) subviewType;
                InitialValueAttributeAccessor viewAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
                AttributeAccessor subviewIdAccessor;
                InverseFlusher<Object> inverseFlusher = InverseFlusher.forAttribute(evm, localCache, viewType, attribute, TypeDescriptor.forType(evm, localCache, this, attribute, subviewType, owner, ownerMapping), owner, ownerMapping);
                InverseRemoveStrategy inverseRemoveStrategy = attribute.getInverseRemoveStrategy();
                ManagedType<?> ownerEntityType = owner == null ? viewType.getJpaManagedType() : owner.managedViewType.getJpaManagedType();
                ViewToEntityMapper viewToEntityMapper;
                boolean fetch = shouldFlushUpdates;
                String parameterName = null;
                String attributeElementIdMapping;
                if (ownerEntityType instanceof EntityType<?> && attribute.getMapping() != null) {
                    ExtendedManagedType<?> extendedManagedType = evm.getMetamodel().getEntityMetamodel().getManagedType(ExtendedManagedType.class, attributeViewType.getEntityClass());
                    attributeElementIdMapping = TypeDescriptor.getAttributeElementIdentifier(evm, (EntityType<?>) ownerEntityType, attribute.getName(), ownerMapping, attribute.getMapping(), extendedManagedType.getType());
                } else {
                    attributeElementIdMapping = ((MappingAttribute<?, ?>) attributeViewType.getIdAttribute()).getMapping();
                }
                subviewIdAccessor = Accessors.forSubviewAssociationId(evm, attributeViewType, attributeElementIdMapping, true);
                Attribute<?, ?> attributeIdAttribute = attributeViewType.getJpaManagedType().getAttribute(attributeElementIdMapping);
                javax.persistence.metamodel.Type<?> attributeIdAttributeType = entityMetamodel.type(JpaMetamodelUtils.resolveFieldClass(attributeViewType.getEntityClass(), attributeIdAttribute));
                List<String> idComponentMappings;
                boolean requiresComponentWiseSetInUpdate = true;
                if (requiresComponentWiseSetInUpdate && attributeIdAttributeType instanceof EmbeddableType<?>) {
                    // If the identifier used for the association is an embeddable, we must collect the individual attribute components since updates don't work on embeddables directly
                    Set<Attribute<?, ?>> idAttributeComponents = (Set<Attribute<?, ?>>) ((EmbeddableType<?>) attributeIdAttributeType).getAttributes();
                    idComponentMappings = new ArrayList<>(idAttributeComponents.size());
                    for (Attribute<?, ?> idAttributeComponent : idAttributeComponents) {
                        idComponentMappings.add(attributeMapping + "." + attributeElementIdMapping + "." + idAttributeComponent.getName());
                    }
                } else {
                    idComponentMappings = Collections.singletonList(attributeMapping + "." + attributeElementIdMapping);
                }
                String[] idAttributeMappings = idComponentMappings.toArray(new String[idComponentMappings.size()]);
                if (attribute.isUpdatable() && ownerEntityType instanceof EntityType<?>) {
                    viewToEntityMapper = createViewToEntityMapper(attributeLocation, evm, localCache, (EntityType<?>) ownerEntityType, attributeName, attributeMapping, attributeViewType, cascadePersist, cascadeUpdate, readOnlyAllowedSubtypes, persistAllowedSubtypes, updateAllowedSubtypes, EntityLoaders.referenceLoaderForAttribute(evm, localCache, attributeViewType, attribute.getViewTypes(), attributeElementIdMapping), owner, ownerMapping);
                    parameterName = attributeName;
                } else {
                    String elementIdentifier;
                    if (ownerEntityType instanceof EntityType<?>) {
                        elementIdentifier = TypeDescriptor.getAttributeElementIdentifier(evm, (EntityType<?>) ownerEntityType, attributeName, ownerMapping, attributeMapping, attributeViewType.getJpaManagedType());
                    } else {
                        elementIdentifier = null;
                    }
                    AttributeAccessor entityIdAccessor = Accessors.forEntityMapping(evm, attributeViewType.getEntityClass(), elementIdentifier);
                    if (shouldFlushUpdates) {
                        viewToEntityMapper = new UpdaterBasedViewToEntityMapper(attributeLocation, evm, subviewType.getJavaType(), readOnlyAllowedSubtypes, persistAllowedSubtypes, updateAllowedSubtypes, EntityLoaders.referenceLoaderForAttribute(evm, localCache, subviewType, attribute), subviewIdAccessor, entityIdAccessor, shouldFlushPersists, owner, ownerMapping, localCache);
                    } else if (!shouldFlushPersists && shouldPassThrough(evm, viewType, attribute)) {
                        viewToEntityMapper = new LoadOnlyViewToEntityMapper(EntityLoaders.referenceLoaderForAttribute(evm, localCache, subviewType, attribute), subviewIdAccessor, entityIdAccessor);
                    } else {
                        viewToEntityMapper = new LoadOrPersistViewToEntityMapper(attributeLocation, evm, subviewType.getJavaType(), readOnlyAllowedSubtypes, persistAllowedSubtypes, updateAllowedSubtypes, EntityLoaders.referenceLoaderForAttribute(evm, localCache, subviewType, attribute), subviewIdAccessor, entityIdAccessor, shouldFlushPersists, owner, ownerMapping, localCache);
                    }
                }
                return new SubviewAttributeFlusher<>(attributeName, attributeMapping, optimisticLockProtected, attribute.isUpdatable(), cascadeDelete, attribute.isOrphanRemoval(), viewOnlyDeleteCascaded, subviewType.getConverter(), fetch, idAttributeMappings, parameterName, passThrough, owner != null, entityAttributeAccessor, viewAttributeAccessor, subviewIdAccessor, viewToEntityMapper, inverseFlusher, inverseRemoveStrategy);
            }
        } else {
            return null;
        }
    } else {
        BasicTypeImpl<?> attributeType = (BasicTypeImpl<?>) ((com.blazebit.persistence.view.metamodel.SingularAttribute<?, ?>) attribute).getType();
        TypeDescriptor elementDescriptor = TypeDescriptor.forType(evm, localCache, this, attribute, attributeType, owner, ownerMapping);
        // Basic attributes like String, Integer but also JPA managed types
        boolean updatable = attribute.isUpdatable();
        if (updatable || elementDescriptor.shouldFlushMutations() || shouldPassThrough(evm, viewType, attribute)) {
            // Basic attributes can normally be updated by queries
            InverseFlusher<Object> inverseFlusher = InverseFlusher.forAttribute(evm, localCache, viewType, attribute, elementDescriptor, owner, ownerMapping);
            InverseRemoveStrategy inverseRemoveStrategy = attribute.getInverseRemoveStrategy();
            String parameterName = attributeName;
            String updateFragment = attributeMapping;
            ManagedType<?> ownerEntityType = owner == null ? viewType.getJpaManagedType() : owner.managedViewType.getJpaManagedType();
            UnmappedBasicAttributeCascadeDeleter deleter;
            if (elementDescriptor.isJpaEntity() && cascadeDelete && ownerEntityType instanceof EntityType<?>) {
                String elementIdAttributeName = TypeDescriptor.getAttributeElementIdentifier(evm, (EntityType<?>) ownerEntityType, attributeName, ownerMapping, attributeMapping, attributeType.getManagedType());
                deleter = new UnmappedBasicAttributeCascadeDeleter(evm, attributeName, entityMetamodel.getManagedType(ExtendedManagedType.class, entityClass).getAttribute(attributeMapping), attributeMapping + "." + elementIdAttributeName, false);
            } else {
                deleter = null;
            }
            // When wanting to read the actual value of non-updatable attributes or writing values to attributes we need the view attribute accessor
            // Whenever we merge or persist, we are going to need that
            AttributeAccessor viewAttributeAccessor;
            if (elementDescriptor.shouldFlushMutations()) {
                viewAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
            } else {
                viewAttributeAccessor = Accessors.forViewAttribute(evm, attribute, true);
            }
            Map.Entry<AttributeAccessor, BasicAttributeFlusher>[] componentFlusherEntries = null;
            if (elementDescriptor.isJpaEmbeddable()) {
                if (!jpaProvider.supportsUpdateSetEmbeddable()) {
                    Set<Attribute<?, ?>> attributes = (Set<Attribute<?, ?>>) attributeType.getManagedType().getAttributes();
                    Map<AttributeAccessor, BasicAttributeFlusher> componentFlushers = new HashMap<>(attributes.size());
                    buildComponentFlushers(evm, viewType.getEntityClass(), attributeType.getJavaType(), attributeName + "_", attributeMapping + ".", "", attributes, componentFlushers);
                    componentFlusherEntries = componentFlushers.entrySet().toArray(new Map.Entry[componentFlushers.size()]);
                }
            }
            return new BasicAttributeFlusher<>(attributeName, attributeMapping, true, optimisticLockProtected, updatable, cascadeDelete, attribute.isOrphanRemoval(), viewOnlyDeleteCascaded, componentFlusherEntries, elementDescriptor, updateFragment, parameterName, entityAttributeAccessor, viewAttributeAccessor, deleter, inverseFlusher, inverseRemoveStrategy);
        } else {
            return null;
        }
    }
}
Also used : CompositeAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.CompositeAttributeFlusher) ViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ViewTypeImplementor) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) InverseRemoveStrategy(com.blazebit.persistence.view.InverseRemoveStrategy) SubviewAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.SubviewAttributeFlusher) UnmappedBasicAttributeCascadeDeleter(com.blazebit.persistence.view.impl.update.flush.UnmappedBasicAttributeCascadeDeleter) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) EntityType(javax.persistence.metamodel.EntityType) TypeDescriptor(com.blazebit.persistence.view.impl.update.flush.TypeDescriptor) InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor) EmbeddableUpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper) LoadOrPersistViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper) Set(java.util.Set) HashSet(java.util.HashSet) UpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.UpdaterBasedViewToEntityMapper) EmbeddableUpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper) LoadOnlyViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper) MappingAttribute(com.blazebit.persistence.view.metamodel.MappingAttribute) SingularAttribute(javax.persistence.metamodel.SingularAttribute) Attribute(javax.persistence.metamodel.Attribute) AbstractMethodAttribute(com.blazebit.persistence.view.impl.metamodel.AbstractMethodAttribute) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) MethodAttribute(com.blazebit.persistence.view.metamodel.MethodAttribute) BasicTypeImpl(com.blazebit.persistence.view.impl.metamodel.BasicTypeImpl) InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) EmbeddableAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.EmbeddableAttributeFlusher) LoadOrPersistViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper) LoadOnlyViewToEntityMapper(com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper) SimpleMapViewToEntityMapper(com.blazebit.persistence.view.impl.update.flush.SimpleMapViewToEntityMapper) UpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.UpdaterBasedViewToEntityMapper) EmbeddableUpdaterBasedViewToEntityMapper(com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper) MapViewToEntityMapper(com.blazebit.persistence.view.impl.entity.MapViewToEntityMapper) ViewToEntityMapper(com.blazebit.persistence.view.impl.entity.ViewToEntityMapper) JpaProvider(com.blazebit.persistence.spi.JpaProvider) ManagedViewTypeImplementor(com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor) ManagedType(javax.persistence.metamodel.ManagedType) BasicType(com.blazebit.persistence.view.metamodel.BasicType) EntityType(javax.persistence.metamodel.EntityType) Type(com.blazebit.persistence.view.metamodel.Type) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) VersionBasicUserType(com.blazebit.persistence.view.spi.type.VersionBasicUserType) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) EmbeddableType(javax.persistence.metamodel.EmbeddableType) ViewType(com.blazebit.persistence.view.metamodel.ViewType) BasicAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.BasicAttributeFlusher) EntityMetamodel(com.blazebit.persistence.parser.EntityMetamodel)

Aggregations

EntityMetamodel (com.blazebit.persistence.parser.EntityMetamodel)2 ExtendedAttribute (com.blazebit.persistence.spi.ExtendedAttribute)2 AttributeAccessor (com.blazebit.persistence.view.impl.accessor.AttributeAccessor)2 LoadOnlyViewToEntityMapper (com.blazebit.persistence.view.impl.entity.LoadOnlyViewToEntityMapper)2 LoadOrPersistViewToEntityMapper (com.blazebit.persistence.view.impl.entity.LoadOrPersistViewToEntityMapper)2 ViewToEntityMapper (com.blazebit.persistence.view.impl.entity.ViewToEntityMapper)2 ManagedViewType (com.blazebit.persistence.view.metamodel.ManagedViewType)2 ViewType (com.blazebit.persistence.view.metamodel.ViewType)2 HashMap (java.util.HashMap)2 ExtendedManagedType (com.blazebit.persistence.spi.ExtendedManagedType)1 JpaProvider (com.blazebit.persistence.spi.JpaProvider)1 InverseRemoveStrategy (com.blazebit.persistence.view.InverseRemoveStrategy)1 InitialValueAttributeAccessor (com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor)1 EmbeddableUpdaterBasedViewToEntityMapper (com.blazebit.persistence.view.impl.entity.EmbeddableUpdaterBasedViewToEntityMapper)1 InverseElementToEntityMapper (com.blazebit.persistence.view.impl.entity.InverseElementToEntityMapper)1 InverseEntityToEntityMapper (com.blazebit.persistence.view.impl.entity.InverseEntityToEntityMapper)1 InverseViewToEntityMapper (com.blazebit.persistence.view.impl.entity.InverseViewToEntityMapper)1 MapViewToEntityMapper (com.blazebit.persistence.view.impl.entity.MapViewToEntityMapper)1 ReferenceEntityLoader (com.blazebit.persistence.view.impl.entity.ReferenceEntityLoader)1 TargetViewClassBasedInverseViewToEntityMapper (com.blazebit.persistence.view.impl.entity.TargetViewClassBasedInverseViewToEntityMapper)1