Search in sources :

Example 11 with MapAttribute

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

the class ProxyFactory method addSetter.

private CtMethod addSetter(AbstractMethodAttribute<?, ?> attribute, CtClass cc, CtField attributeField, String methodName, CtField mutableStateField, boolean dirtyChecking, boolean isId) throws CannotCompileException, NotFoundException {
    FieldInfo finfo = attributeField.getFieldInfo2();
    String fieldType = finfo.getDescriptor();
    String desc = "(" + fieldType + ")V";
    ConstPool cp = finfo.getConstPool();
    MethodInfo minfo = new MethodInfo(cp, methodName, desc);
    minfo.setAccessFlags(AccessFlag.PUBLIC);
    String fieldName = finfo.getName();
    StringBuilder sb = new StringBuilder();
    sb.append("{\n");
    boolean invalidSetter = false;
    // When the declaring type is updatable/creatable we only allow setting the id value on new objects
    if (isId) {
        if (attribute != null && attribute.getDeclaringType().isCreatable()) {
            sb.append("\tif ($0.$$_kind != (byte) 2) {\n");
            sb.append("\t\tthrow new IllegalArgumentException(\"Updating the id attribute '").append(attribute.getName()).append("' is only allowed for new entity view objects created via EntityViewManager.create()!\");\n");
            sb.append("\t}\n");
        } else if (attribute != null && attribute.getDeclaringType().isUpdatable()) {
            sb.append("\tthrow new IllegalArgumentException(\"Updating the id attribute '").append(attribute.getName()).append("' is only allowed for new entity view objects created via EntityViewManager.create()!\");\n");
            invalidSetter = true;
        }
    }
    // Disallow calling the setter on a mutable only relation with objects of a different identity as that might indicate a programming error
    if (attribute != null && attribute.getDirtyStateIndex() != -1 && !attribute.isUpdatable() && (attribute.getDeclaringType().isCreatable() || attribute.getDeclaringType().isUpdatable())) {
        sb.append("\tObject tmp;\n");
        sb.append("\tif ($1 != $0.").append(fieldName);
        if (attribute.isCollection()) {
        // TODO: We could theoretically support collections too by looking into them and asserting equality element-wise
        } else {
            SingularAttribute<?, ?> singularAttribute = (SingularAttribute<?, ?>) attribute;
            Type<?> type = singularAttribute.getType();
            if (attribute.isSubview()) {
                if (!(type instanceof FlatViewType<?>)) {
                    String idMethodName = ((ViewType<?>) type).getIdAttribute().getJavaMethod().getName();
                    sb.append(" && ");
                    sb.append("($1 == null || (tmp = $1.");
                    sb.append(idMethodName);
                    sb.append("()) == null || !java.util.Objects.equals(tmp, $0.");
                    sb.append(fieldName);
                    sb.append('.').append(idMethodName);
                    sb.append("()))");
                }
            } else {
                BasicTypeImpl<?> basicType = (BasicTypeImpl<?>) type;
                boolean jpaEntity = basicType.isJpaEntity();
                if (jpaEntity) {
                    IdentifiableType<?> identifiableType = (IdentifiableType<?>) basicType.getManagedType();
                    for (javax.persistence.metamodel.SingularAttribute<?, ?> idAttribute : JpaMetamodelUtils.getIdAttributes(identifiableType)) {
                        Class<?> idClass = JpaMetamodelUtils.resolveFieldClass(basicType.getJavaType(), idAttribute);
                        String idAccessor = addIdAccessor(cc, identifiableType, idAttribute, pool.get(idClass.getName()));
                        sb.append(" && ");
                        sb.append("($1 == null || (tmp = ");
                        sb.append(idAccessor);
                        sb.append("($1)) == null || !java.util.Objects.equals(tmp, ");
                        sb.append(idAccessor);
                        sb.append("($0.");
                        sb.append(fieldName);
                        sb.append(")))");
                    }
                }
            }
        }
        sb.append(") {\n");
        sb.append("\t\tthrow new IllegalArgumentException(\"Updating the mutable-only attribute '").append(attribute.getName()).append("' with a value that has not the same identity is not allowed! Consider making the attribute updatable or update the value directly instead of replacing it!\");\n");
        sb.append("\t}\n");
    }
    if (attribute != null && attribute.isUpdatable() && dirtyChecking) {
        if (attribute.isCollection()) {
            if (strictCascadingCheck) {
                // With strict cascading checks enabled, we don't allow setting collections of mutable subviews
                boolean mutableElement = !attribute.getUpdateCascadeAllowedSubtypes().isEmpty() || !attribute.getPersistCascadeAllowedSubtypes().isEmpty();
                if (mutableElement && ((AbstractMethodPluralAttribute<?, ?, ?>) attribute).getElementType().getMappingType() != Type.MappingType.BASIC) {
                    sb.append("\t\tthrow new IllegalArgumentException(\"Replacing a collection that PERSIST or UPDATE cascades is prohibited by default! Instead, replace the contents by doing clear() and addAll()!\");\n");
                }
            }
        } else {
            // Only consider subviews here for now
            if (attribute.isSubview()) {
                String subtypeArray = addAllowedSubtypeField(cc, attribute);
                addParentRequiringUpdateSubtypesField(cc, attribute);
                addParentRequiringCreateSubtypesField(cc, attribute);
                sb.append("\tif ($1 != null) {\n");
                sb.append("\t\tClass c;\n");
                sb.append("\t\tboolean isNew;\n");
                sb.append("\t\tif ($1 instanceof ").append(EntityViewProxy.class.getName()).append(") {\n");
                sb.append("\t\t\tc = ((").append(EntityViewProxy.class.getName()).append(") $1).$$_getEntityViewClass();\n");
                sb.append("\t\t\tisNew = ((").append(EntityViewProxy.class.getName()).append(") $1).$$_isNew();\n");
                sb.append("\t\t} else {\n");
                sb.append("\t\t\tc = $1.getClass();\n");
                sb.append("\t\t\tisNew = false;\n");
                sb.append("\t\t}\n");
                sb.append("\t\tif (!").append(attributeField.getDeclaringClass().getName()).append('#').append(attribute.getName()).append("_$$_subtypes.contains(c)) {\n");
                sb.append("\t\t\tthrow new IllegalArgumentException(");
                sb.append("\"Allowed subtypes for attribute '").append(attribute.getName()).append("' are [").append(subtypeArray).append("] but got an instance of: \"");
                sb.append(".concat(c.getName())");
                sb.append(");\n");
                sb.append("\t\t}\n");
                if (strictCascadingCheck) {
                    sb.append("\t\tif ($0 != $1 && !isNew && ").append(attributeField.getDeclaringClass().getName()).append('#').append(attribute.getName()).append("_$$_parentRequiringUpdateSubtypes.contains(c) && !((").append(DirtyTracker.class.getName()).append(") $1).$$_hasParent()) {\n");
                    sb.append("\t\t\tthrow new IllegalArgumentException(");
                    sb.append("\"Setting instances of type [\" + c.getName() + \"] on attribute '").append(attribute.getName()).append("' is not allowed until they are assigned to an attribute that cascades the type! ");
                    sb.append("If you want this attribute to cascade, annotate it with @UpdatableMapping(cascade = { UPDATE }). You can also turn off strict cascading checks by setting ConfigurationProperties.UPDATER_STRICT_CASCADING_CHECK to false\"");
                    sb.append(");\n");
                    sb.append("\t\t}\n");
                    sb.append("\t\tif ($0 != $1 && isNew && ").append(attributeField.getDeclaringClass().getName()).append('#').append(attribute.getName()).append("_$$_parentRequiringCreateSubtypes.contains(c) && !((").append(DirtyTracker.class.getName()).append(") $1).$$_hasParent()) {\n");
                    sb.append("\t\t\tthrow new IllegalArgumentException(");
                    sb.append("\"Setting instances of type [\" + c.getName() + \"] on attribute '").append(attribute.getName()).append("' is not allowed until they are assigned to an attribute that cascades the type! ");
                    sb.append("If you want this attribute to cascade, annotate it with @UpdatableMapping(cascade = { PERSIST }). You can also turn off strict cascading checks by setting ConfigurationProperties.UPDATER_STRICT_CASCADING_CHECK to false\"");
                    sb.append(");\n");
                    sb.append("\t\t}\n");
                }
                sb.append("\t}\n");
            }
        }
    }
    if (attribute != null && attribute.getDirtyStateIndex() != -1) {
        int mutableStateIndex = attribute.getDirtyStateIndex();
        // Unset previous object parent
        if (attribute.isCollection()) {
            sb.append("\tif ($0.").append(fieldName).append(" != null && $0.").append(fieldName).append(" != $1) {\n");
            if (attribute instanceof MapAttribute<?, ?, ?>) {
                sb.append("\t\tif ($0.").append(fieldName).append(" instanceof ").append(RecordingMap.class.getName()).append(") {\n");
                sb.append("\t\t\t((").append(RecordingMap.class.getName()).append(") $0.").append(fieldName).append(").$$_unsetParent();\n");
                sb.append("\t\t}\n");
            } else {
                sb.append("\t\tif ($0.").append(fieldName).append(" instanceof ").append(RecordingCollection.class.getName()).append(") {\n");
                sb.append("\t\t\t((").append(RecordingCollection.class.getName()).append(") $0.").append(fieldName).append(").$$_unsetParent();\n");
                sb.append("\t\t}\n");
            }
            sb.append("\t}\n");
        } else if (attribute.isSubview()) {
            if (attribute.isUpdatableOnly() && !attribute.isCorrelated()) {
                sb.append("\tif ($0.").append(fieldName).append(" != $1 && $0.").append(fieldName).append(" instanceof ").append(MutableStateTrackable.class.getName()).append(") {\n");
                sb.append("\t\t\t((").append(MutableStateTrackable.class.getName()).append(") $0.").append(fieldName).append(").$$_removeReadOnlyParent($0, ").append(mutableStateIndex).append(");\n");
                sb.append("\t} else if ($0.").append(fieldName).append(" != $1 && $0.").append(fieldName).append(" instanceof ").append(BasicDirtyTracker.class.getName()).append(") {\n");
                sb.append("\t\t\t((").append(BasicDirtyTracker.class.getName()).append(") $0.").append(fieldName).append(").$$_unsetParent();\n");
            } else {
                sb.append("\tif ($0.").append(fieldName).append(" != $1 && $0.").append(fieldName).append(" instanceof ").append(BasicDirtyTracker.class.getName()).append(") {\n");
                sb.append("\t\t((").append(BasicDirtyTracker.class.getName()).append(") $0.").append(fieldName).append(").$$_unsetParent();\n");
            }
            sb.append("\t}\n");
        }
        if (mutableStateField != null) {
            // this.mutableState[mutableStateIndex] = $1
            sb.append("\t$0.").append(mutableStateField.getName()).append("[").append(mutableStateIndex).append("] = ");
            renderValueForArray(sb, attributeField.getType(), "$1");
        }
        if (dirtyChecking) {
            // this.dirty = true
            sb.append("\t$0.$$_markDirty(").append(mutableStateIndex).append(");\n");
            // Set new objects parent
            if (attribute.isCollection() || attribute.isSubview()) {
                sb.append("\tif ($0.$$_initialized && $1 != null && $0.").append(fieldName).append(" != $1) {\n");
                if (attribute.isCollection()) {
                    if (attribute instanceof MapAttribute<?, ?, ?>) {
                        sb.append("\t\tif ($1 instanceof ").append(RecordingMap.class.getName()).append(") {\n");
                        sb.append("\t\t\t((").append(RecordingMap.class.getName()).append(") $1).$$_setParent($0, ").append(mutableStateIndex).append(");\n");
                        sb.append("\t\t}\n");
                    } else {
                        sb.append("\t\tif ($1 instanceof ").append(RecordingCollection.class.getName()).append(") {\n");
                        sb.append("\t\t\t((").append(RecordingCollection.class.getName()).append(") $1).$$_setParent($0, ").append(mutableStateIndex).append(");\n");
                        sb.append("\t\t}\n");
                    }
                } else if (attribute.isSubview()) {
                    // Correlated attributes are treated special, we don't consider correlated attributes read-only parents
                    if (attribute.isUpdatableOnly() && !attribute.isCorrelated()) {
                        sb.append("\t\tif ($1 instanceof ").append(MutableStateTrackable.class.getName()).append(") {\n");
                        sb.append("\t\t\t((").append(MutableStateTrackable.class.getName()).append(") $1).$$_addReadOnlyParent($0, ").append(mutableStateIndex).append(");\n");
                        sb.append("\t\t} else if ($1 instanceof ").append(BasicDirtyTracker.class.getName()).append(") {\n");
                        sb.append("\t\t\t((").append(BasicDirtyTracker.class.getName()).append(") $1).$$_setParent($0, ").append(mutableStateIndex).append(");\n");
                    } else {
                        sb.append("\t\tif ($1 instanceof ").append(BasicDirtyTracker.class.getName()).append(") {\n");
                        sb.append("\t\t\t((").append(BasicDirtyTracker.class.getName()).append(") $1).$$_setParent($0, ").append(mutableStateIndex).append(");\n");
                    }
                    sb.append("\t\t}\n");
                }
                sb.append("\t}\n");
            }
        }
    }
    if (!invalidSetter) {
        sb.append("\t$0.").append(fieldName).append(" = $1;\n");
    }
    sb.append('}');
    CtMethod method = CtMethod.make(minfo, cc);
    method.setBody(sb.toString());
    cc.addMethod(method);
    return method;
}
Also used : ConstPool(javassist.bytecode.ConstPool) IdentifiableType(javax.persistence.metamodel.IdentifiableType) MutableStateTrackable(com.blazebit.persistence.view.spi.type.MutableStateTrackable) BasicTypeImpl(com.blazebit.persistence.view.impl.metamodel.BasicTypeImpl) BasicDirtyTracker(com.blazebit.persistence.view.spi.type.BasicDirtyTracker) SingularAttribute(com.blazebit.persistence.view.metamodel.SingularAttribute) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) MethodInfo(javassist.bytecode.MethodInfo) FieldInfo(javassist.bytecode.FieldInfo) FlatViewType(com.blazebit.persistence.view.metamodel.FlatViewType) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) ViewType(com.blazebit.persistence.view.metamodel.ViewType) FlatViewType(com.blazebit.persistence.view.metamodel.FlatViewType) CtMethod(javassist.CtMethod)

Example 12 with MapAttribute

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

the class EntityViewUpdaterImpl method createPluralAttributeFlusher.

private DirtyAttributeFlusher<?, ?, ?> createPluralAttributeFlusher(EntityViewManagerImpl evm, Map<Object, EntityViewUpdaterImpl> localCache, ManagedViewTypeImplementor<?> viewType, String idAttributeName, FlushStrategy flushStrategy, AbstractMethodAttribute<?, ?> attribute, DirtyAttributeFlusher<?, ?, ?> ownerIdFlusher, EntityViewUpdaterImpl owner, String ownerMapping) {
    EntityMetamodel entityMetamodel = evm.getMetamodel().getEntityMetamodel();
    Class<?> entityClass = viewType.getEntityClass();
    ExtendedManagedType managedType = entityMetamodel.getManagedType(ExtendedManagedType.class, entityClass);
    String attributeName = attribute.getName();
    String attributeMapping = attribute.getMapping();
    AttributeAccessor entityAttributeAccessor = Accessors.forEntityMapping(evm, attribute);
    boolean cascadeDelete = attribute.isDeleteCascaded();
    boolean viewOnlyDeleteCascaded = cascadeDelete && !managedType.getAttribute(attributeMapping).isDeleteCascaded();
    boolean optimisticLockProtected = attribute.isOptimisticLockProtected();
    JpaProvider jpaProvider = evm.getJpaProvider();
    PluralAttribute<?, ?, ?> pluralAttribute = (PluralAttribute<?, ?, ?>) attribute;
    InitialValueAttributeAccessor viewAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
    ManagedType<?> ownerManagedType = owner == null ? viewType.getJpaManagedType() : owner.managedViewType.getJpaManagedType();
    EntityType<?> ownerEntityType = ownerManagedType instanceof EntityType<?> ? (EntityType<?>) ownerManagedType : null;
    DirtyAttributeFlusher<?, ?, ?> attributeOwnerFlusher;
    if (attributeMapping == null || ownerEntityType == null) {
        // In case of cascading only attributes i.e. correlations, we use the owner id flusher as it's not updatable anyway
        attributeOwnerFlusher = ownerIdFlusher;
    } else {
        Map<String, String> joinTableOwnerProperties;
        if (ownerMapping == null) {
            joinTableOwnerProperties = jpaProvider.getJoinMappingPropertyNames(ownerEntityType, ownerMapping, attributeMapping);
        } else {
            joinTableOwnerProperties = jpaProvider.getJoinMappingPropertyNames(ownerEntityType, ownerMapping, ownerMapping + "." + attributeMapping);
        }
        if (joinTableOwnerProperties.size() != 1) {
            String idMapping = ownerIdFlusher.getMapping();
            String prefix;
            if (idMapping.endsWith(".")) {
                prefix = idMapping;
            } else {
                prefix = idMapping + ".";
            }
            for (String joinTableOwnerProperty : joinTableOwnerProperties.keySet()) {
                if (!joinTableOwnerProperty.startsWith(prefix)) {
                    throw new IllegalArgumentException("Multiple joinable owner properties for attribute '" + attributeName + "' of " + ownerEntityType.getJavaType().getName() + " found which is not yet supported. Consider using the primary key instead!");
                }
            }
            attributeOwnerFlusher = ownerIdFlusher;
        } else if (ownerIdFlusher.getMapping().equals(joinTableOwnerProperties.values().iterator().next())) {
            attributeOwnerFlusher = ownerIdFlusher;
        } else {
            attributeOwnerFlusher = findSingularAttributeFlusherByMapping(evm, localCache, owner, viewType, attributeName, joinTableOwnerProperties.keySet().iterator().next());
        }
    }
    TypeDescriptor elementDescriptor = TypeDescriptor.forType(evm, localCache, this, attribute, pluralAttribute.getElementType(), owner, ownerMapping);
    boolean collectionUpdatable = attribute.isUpdatable();
    CollectionRemoveListener elementRemoveListener = createOrphanRemoveListener(attribute, elementDescriptor);
    CollectionRemoveListener elementCascadeDeleteListener = createCascadeDeleteListener(attribute, elementDescriptor);
    boolean jpaProviderDeletesCollection;
    boolean supportsCollectionDml = jpaProvider.supportsInsertStatement();
    if (elementDescriptor.getAttributeIdAttributeName() != null) {
        jpaProviderDeletesCollection = jpaProvider.supportsJoinTableCleanupOnDelete();
    } else {
        jpaProviderDeletesCollection = jpaProvider.supportsCollectionTableCleanupOnDelete();
    }
    if (attribute instanceof MapAttribute<?, ?, ?>) {
        MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
        TypeDescriptor keyDescriptor = TypeDescriptor.forType(evm, localCache, this, attribute, mapAttribute.getKeyType(), owner, ownerMapping);
        // TODO: currently there is no possibility to set this
        CollectionRemoveListener keyRemoveListener = null;
        CollectionRemoveListener keyCascadeDeleteListener = null;
        if (collectionUpdatable || keyDescriptor.shouldFlushMutations() || elementDescriptor.shouldFlushMutations() || shouldPassThrough(evm, viewType, attribute)) {
            MapViewToEntityMapper mapper = new SimpleMapViewToEntityMapper(keyDescriptor.getViewToEntityMapper(), elementDescriptor.getViewToEntityMapper());
            MapViewToEntityMapper loadOnlyMapper = new SimpleMapViewToEntityMapper(keyDescriptor.getLoadOnlyViewToEntityMapper(), elementDescriptor.getLoadOnlyViewToEntityMapper());
            MapInstantiatorImplementor<?, ?> mapInstantiator = attribute.getMapInstantiator();
            return new MapAttributeFlusher<Object, RecordingMap<Map<?, ?>, ?, ?>>(attributeName, attributeMapping, owner == null ? entityClass : owner.fullEntityLoader.getEntityClass(), idAttributeName, ownerMapping, attributeOwnerFlusher, createPluralAttributeSubFlusher(evm, localCache, viewType, attribute, "element", mapAttribute.getElementType(), owner, ownerMapping), supportsCollectionDml, flushStrategy, entityAttributeAccessor, viewAttributeAccessor, optimisticLockProtected, collectionUpdatable, keyCascadeDeleteListener, elementCascadeDeleteListener, keyRemoveListener, elementRemoveListener, viewOnlyDeleteCascaded, jpaProviderDeletesCollection, keyDescriptor, elementDescriptor, mapper, loadOnlyMapper, mapInstantiator);
        } else {
            return null;
        }
    } else {
        if (collectionUpdatable || elementDescriptor.shouldFlushMutations() || shouldPassThrough(evm, viewType, attribute)) {
            InverseFlusher<Object> inverseFlusher = InverseFlusher.forAttribute(evm, localCache, viewType, attribute, elementDescriptor, owner, ownerMapping);
            InverseRemoveStrategy inverseRemoveStrategy = attribute.getInverseRemoveStrategy();
            CollectionInstantiatorImplementor<?, ?> collectionInstantiator = attribute.getCollectionInstantiator();
            if (pluralAttribute.isIndexed()) {
                return new IndexedListAttributeFlusher<Object, RecordingList<List<?>>>(attributeName, attributeMapping, owner == null ? entityClass : owner.fullEntityLoader.getEntityClass(), idAttributeName, ownerMapping, attributeOwnerFlusher, createPluralAttributeSubFlusher(evm, localCache, viewType, attribute, "element", pluralAttribute.getElementType(), owner, ownerMapping), supportsCollectionDml, flushStrategy, entityAttributeAccessor, viewAttributeAccessor, optimisticLockProtected, collectionUpdatable, viewOnlyDeleteCascaded, jpaProviderDeletesCollection, elementCascadeDeleteListener, elementRemoveListener, collectionInstantiator, elementDescriptor, inverseFlusher, inverseRemoveStrategy);
            } else {
                return new CollectionAttributeFlusher(attributeName, attributeMapping, owner == null ? entityClass : owner.fullEntityLoader.getEntityClass(), idAttributeName, ownerMapping, attributeOwnerFlusher, createPluralAttributeSubFlusher(evm, localCache, viewType, attribute, "element", pluralAttribute.getElementType(), owner, ownerMapping), supportsCollectionDml, flushStrategy, entityAttributeAccessor, viewAttributeAccessor, optimisticLockProtected, collectionUpdatable, viewOnlyDeleteCascaded, jpaProviderDeletesCollection, elementCascadeDeleteListener, elementRemoveListener, collectionInstantiator, elementDescriptor, inverseFlusher, inverseRemoveStrategy);
            }
        } else {
            return null;
        }
    }
}
Also used : InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) MapAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.MapAttributeFlusher) InverseRemoveStrategy(com.blazebit.persistence.view.InverseRemoveStrategy) CollectionRemoveListener(com.blazebit.persistence.view.impl.collection.CollectionRemoveListener) ViewCollectionRemoveListener(com.blazebit.persistence.view.impl.update.flush.ViewCollectionRemoveListener) EntityCollectionRemoveListener(com.blazebit.persistence.view.impl.update.flush.EntityCollectionRemoveListener) IndexedListAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.IndexedListAttributeFlusher) List(java.util.List) RecordingList(com.blazebit.persistence.view.impl.collection.RecordingList) ArrayList(java.util.ArrayList) CollectionAttributeFlusher(com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher) JpaProvider(com.blazebit.persistence.spi.JpaProvider) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) TypeDescriptor(com.blazebit.persistence.view.impl.update.flush.TypeDescriptor) SimpleMapViewToEntityMapper(com.blazebit.persistence.view.impl.update.flush.SimpleMapViewToEntityMapper) MapViewToEntityMapper(com.blazebit.persistence.view.impl.entity.MapViewToEntityMapper) InitialValueAttributeAccessor(com.blazebit.persistence.view.impl.accessor.InitialValueAttributeAccessor) AttributeAccessor(com.blazebit.persistence.view.impl.accessor.AttributeAccessor) SimpleMapViewToEntityMapper(com.blazebit.persistence.view.impl.update.flush.SimpleMapViewToEntityMapper) EntityMetamodel(com.blazebit.persistence.parser.EntityMetamodel) Map(java.util.Map) RecordingMap(com.blazebit.persistence.view.impl.collection.RecordingMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Example 13 with MapAttribute

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

the class EntityViewBuilderBaseImpl method withCollectionBuilder.

private <E> EntityViewNestedBuilder<E, ? extends BuilderType, ?> withCollectionBuilder(AbstractAttribute<?, ?> attr) {
    if (attr instanceof MapAttribute<?, ?, ?>) {
        throw new IllegalArgumentException("Can not add element to map attribute. Use withMapBuilder()!");
    } else if (attr instanceof SingularAttribute<?, ?>) {
        throw new IllegalArgumentException("Can not add element to singular attribute. Use withBuilder()!");
    }
    checkType(attr.getElementType(), "element", attr);
    Map<ManagedViewType<? extends E>, String> inheritanceSubtypeMappings = ((PluralAttribute<?, ?, E>) attr).getElementInheritanceSubtypeMappings();
    return new EntityViewNestedBuilderImpl<>(evm, (ManagedViewTypeImplementor<E>) attr.getElementType(), inheritanceSubtypeMappings, optionalParameters, (BuilderType) this, new CollectionEntityViewBuilderListener(getCollection(attr)));
}
Also used : MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) CollectionEntityViewBuilderListener(com.blazebit.persistence.view.CollectionEntityViewBuilderListener)

Example 14 with MapAttribute

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

the class EntityViewBuilderBaseImpl method withBuilder.

@Override
public <K, V> EntityViewNestedBuilder<K, ? extends EntityViewNestedBuilder<V, ? extends BuilderType, ?>, ?> withBuilder(MapAttribute<ViewType, K, V> attribute) {
    AbstractAttribute<?, ?> attr = getAttribute(attribute);
    checkType(((MapAttribute<?, ?, ?>) attr).getKeyType(), "key", attr);
    checkType(attr.getElementType(), "element", attr);
    MapKeyEntityViewBuilderListener listener = new MapKeyEntityViewBuilderListener(getMap(attr));
    Map<ManagedViewType<? extends V>, String> inheritanceSubtypeMappings = ((PluralAttribute<?, ?, V>) attr).getElementInheritanceSubtypeMappings();
    EntityViewNestedBuilder<V, ? extends BuilderType, ?> valueBuilder = new EntityViewNestedBuilderImpl<>(evm, (ManagedViewTypeImplementor<V>) attr.getElementType(), inheritanceSubtypeMappings, optionalParameters, (BuilderType) this, listener);
    Map<ManagedViewType<? extends K>, String> keyInheritanceSubtypeMappings = ((MapAttribute<?, K, ?>) attr).getKeyInheritanceSubtypeMappings();
    return new EntityViewNestedBuilderImpl<>(evm, (ManagedViewTypeImplementor<K>) attr.getElementType(), keyInheritanceSubtypeMappings, optionalParameters, valueBuilder, listener);
}
Also used : ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) MapKeyEntityViewBuilderListener(com.blazebit.persistence.view.MapKeyEntityViewBuilderListener)

Example 15 with MapAttribute

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

the class EntityViewBuilderBaseImpl method withMapBuilder.

private <K, V> EntityViewNestedBuilder<K, ? extends EntityViewNestedBuilder<V, ? extends BuilderType, ?>, ?> withMapBuilder(AbstractAttribute<?, ?> attr) {
    checkAttribute(attr, MapAttribute.class, "Map");
    checkType(((MapAttribute<?, ?, ?>) attr).getKeyType(), "key", attr);
    checkType(attr.getElementType(), "element", attr);
    MapKeyEntityViewBuilderListener listener = new MapKeyEntityViewBuilderListener(getMap(attr));
    Map<ManagedViewType<? extends V>, String> inheritanceSubtypeMappings = ((PluralAttribute<?, ?, V>) attr).getElementInheritanceSubtypeMappings();
    EntityViewNestedBuilder<V, ? extends BuilderType, ?> valueBuilder = new EntityViewNestedBuilderImpl<>(evm, (ManagedViewTypeImplementor<V>) attr.getElementType(), inheritanceSubtypeMappings, optionalParameters, (BuilderType) this, listener);
    Map<ManagedViewType<? extends K>, String> keyInheritanceSubtypeMappings = ((MapAttribute<?, K, ?>) attr).getKeyInheritanceSubtypeMappings();
    return new EntityViewNestedBuilderImpl<>(evm, (ManagedViewTypeImplementor<K>) attr.getElementType(), keyInheritanceSubtypeMappings, optionalParameters, valueBuilder, listener);
}
Also used : ManagedViewType(com.blazebit.persistence.view.metamodel.ManagedViewType) MapAttribute(com.blazebit.persistence.view.metamodel.MapAttribute) PluralAttribute(com.blazebit.persistence.view.metamodel.PluralAttribute) MapKeyEntityViewBuilderListener(com.blazebit.persistence.view.MapKeyEntityViewBuilderListener)

Aggregations

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