Search in sources :

Example 6 with ExtendedAttribute

use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.

the class EntitySelectResolveVisitor method visit.

@Override
public void visit(PathExpression expression) {
    if (expression.getField() == null) {
        /**
         * We need to resolve entity selects because hibernate will
         * select every entity attribute. Since we need every select in
         * the group by (because of DB2) we need to resolve such entity
         * selects here
         */
        rootNode = ((JoinNode) expression.getBaseNode());
        if (rootNode == null) {
            // This is an alias expression to a complex expression
            return;
        }
        EntityType<?> entityType = m.getEntity(rootNode.getJavaType());
        if (entityType == null) {
            // ignore if the expression is not an entity
            return;
        }
        // TODO: a polymorphic query will fail because we don't collect subtype properties
        ExtendedManagedType<?> extendedManagedType = m.getManagedType(ExtendedManagedType.class, entityType);
        Set<String> attributePaths;
        if (rootNode.getValuesIdNames() != null && !rootNode.getValuesIdNames().isEmpty()) {
            attributePaths = rootNode.getValuesIdNames();
        } else {
            attributePaths = Collections.emptySet();
        }
        Map<String, ExtendedAttribute<?, ?>> ownedSingularAttributes = (Map<String, ExtendedAttribute<?, ?>>) (Map) extendedManagedType.getOwnedSingularAttributes();
        Collection<String> propertyPaths = JpaUtils.getEmbeddedPropertyPaths(ownedSingularAttributes, null, jpaProvider.needsElementCollectionIdCutoff(), true);
        for (String propertyPath : propertyPaths) {
            // Skip if the attribute is not in the desired attribute paths
            if (!attributePaths.isEmpty() && !attributePaths.contains(propertyPath)) {
                continue;
            }
            ExtendedAttribute<?, ?> extendedAttribute = ownedSingularAttributes.get(propertyPath);
            Attribute<?, ?> attr = extendedAttribute.getAttribute();
            boolean resolve = false;
            if (JpaMetamodelUtils.isAssociation(attr) && !attr.isCollection()) {
                resolve = true;
            } else if (ExpressionUtils.getFetchType(attr) == FetchType.EAGER) {
                if (attr.getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) {
                    throw new UnsupportedOperationException("Eager element collections are not supported");
                }
                resolve = true;
            }
            if (resolve) {
                List<PathElementExpression> paths = new ArrayList<>(expression.getExpressions().size() + 1);
                paths.addAll(expression.getExpressions());
                for (Attribute<?, ?> attribute : extendedAttribute.getAttributePath()) {
                    paths.add(new PropertyExpression(attribute.getName()));
                }
                PathExpression attrPath = new PathExpression(paths);
                attrPath.setPathReference(new SimplePathReference(rootNode, propertyPath, m.type(extendedAttribute.getElementClass())));
                pathExpressions.add(attrPath);
            }
        }
    }
}
Also used : ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ArrayList(java.util.ArrayList) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) Map(java.util.Map)

Example 7 with ExtendedAttribute

use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.

the class CachingJpaProvider method isDeleteCascaded.

@Override
public boolean isDeleteCascaded(ManagedType<?> ownerType, String attributeName) {
    ExtendedManagedType managedType = entityMetamodel.getManagedType(ExtendedManagedType.class, ownerType);
    ExtendedAttribute attribute = (ExtendedAttribute) managedType.getAttributes().get(attributeName);
    return attribute != null && attribute.isDeleteCascaded();
}
Also used : ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType)

Example 8 with ExtendedAttribute

use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.

the class ConstantifiedJoinNodeAttributeCollector method visit.

@Override
public void visit(PathExpression expr) {
    PathReference pathReference = expr.getPathReference();
    if (pathReference == null) {
        ((SelectInfo) aliasManager.getAliasInfo(expr.toString())).getExpression().accept(this);
        return;
    }
    JoinNode baseNode = (JoinNode) pathReference.getBaseNode();
    if (pathReference.getField() == null) {
        if (inKey) {
            // We constantify collection as a whole to a single element when reaching this point
            Map<String, Boolean> attributes = new HashMap<>(1);
            attributes.put(KEY_FUNCTION, innerJoin);
            constantifiedJoinNodeAttributes.put(baseNode, attributes);
        } else if (baseNode.getType() instanceof ManagedType<?>) {
            // Here we have a predicate like `d = d2` which is the same as `d.id = d2.id`
            Map<String, Boolean> attributes = constantifiedJoinNodeAttributes.get(baseNode);
            if (attributes == null) {
                attributes = new HashMap<>();
                constantifiedJoinNodeAttributes.put(baseNode, attributes);
            }
            ExtendedManagedType<?> managedType = metamodel.getManagedType(ExtendedManagedType.class, baseNode.getManagedType());
            for (SingularAttribute<?, ?> idAttribute : managedType.getIdAttributes()) {
                addAttribute("", idAttribute, attributes);
            }
        }
        return;
    }
    ExtendedManagedType<?> managedType = metamodel.getManagedType(ExtendedManagedType.class, baseNode.getManagedType());
    ExtendedAttribute<?, ?> extendedAttribute = managedType.getAttribute(pathReference.getField());
    Attribute attr = extendedAttribute.getAttribute();
    // We constantify collection as a whole to a single element when reaching this point
    if (attr instanceof PluralAttribute<?, ?, ?>) {
        if (inKey) {
            Map<String, Boolean> attributes = new HashMap<>(1);
            attributes.put(KEY_FUNCTION, innerJoin);
            constantifiedJoinNodeAttributes.put(baseNode, attributes);
        }
        return;
    }
    int dotIndex = expr.getField().lastIndexOf('.');
    SingularAttribute<?, ?> singularAttr = (SingularAttribute<?, ?>) attr;
    String associationName = getSingleValuedIdAccessAssociationName(pathReference.getField(), extendedAttribute);
    Object baseNodeKey;
    String prefix;
    if (associationName == null) {
        baseNodeKey = baseNode;
        prefix = attr.getDeclaringType() instanceof EmbeddableType<?> ? pathReference.getField().substring(0, dotIndex + 1) : "";
    } else {
        baseNodeKey = new AbstractMap.SimpleEntry<>(baseNode, associationName);
        if (attr.getDeclaringType() instanceof EmbeddableType<?>) {
            prefix = pathReference.getField().substring(associationName.length() + 1, dotIndex + 1);
        } else {
            prefix = "";
        }
    }
    Map<String, Boolean> attributes = constantifiedJoinNodeAttributes.get(baseNodeKey);
    if (attributes == null) {
        attributes = new HashMap<>();
        constantifiedJoinNodeAttributes.put(baseNodeKey, attributes);
    }
    addAttribute(prefix, singularAttr, attributes);
    StringBuilder attributeNameBuilder = null;
    Map<String, Boolean> baseNodeAttributes = null;
    String associationNamePrefix = associationName == null ? "" : associationName + '.';
    // Also add all attributes to the set that resolve to the same column names i.e. which are essentially equivalent
    Map<String, Boolean> newAttributes = new HashMap<>();
    for (Map.Entry<String, Boolean> entry : attributes.entrySet()) {
        String attribute = entry.getKey();
        if (attribute != KEY_FUNCTION) {
            for (ExtendedAttribute<?, ?> columnEquivalentAttribute : managedType.getAttribute(associationNamePrefix + attribute).getColumnEquivalentAttributes()) {
                List<Attribute<?, ?>> attributePath = columnEquivalentAttribute.getAttributePath();
                String attributeName;
                if (attributePath.size() == 1) {
                    attributeName = attributePath.get(0).getName();
                } else {
                    if (attributeNameBuilder == null) {
                        attributeNameBuilder = new StringBuilder();
                    } else {
                        attributeNameBuilder.setLength(0);
                    }
                    attributeNameBuilder.append(attributePath.get(0).getName());
                    for (int i = 1; i < attributePath.size(); i++) {
                        attributeNameBuilder.append('.');
                        attributeNameBuilder.append(attributePath.get(i).getName());
                    }
                    attributeName = attributeNameBuilder.toString();
                }
                // Be careful with single valued association ids, they have a different baseNodeKey
                if (!associationNamePrefix.isEmpty() && !attributeName.startsWith(associationNamePrefix)) {
                    if (baseNodeAttributes == null) {
                        baseNodeAttributes = constantifiedJoinNodeAttributes.get(baseNode);
                        if (baseNodeAttributes == null) {
                            baseNodeAttributes = new HashMap<>();
                            constantifiedJoinNodeAttributes.put(baseNode, baseNodeAttributes);
                        }
                    }
                    baseNodeAttributes.put(attributeName, entry.getValue());
                } else {
                    newAttributes.put(attributeName, entry.getValue());
                }
            }
        }
    }
    attributes.putAll(newAttributes);
}
Also used : PathReference(com.blazebit.persistence.parser.expression.PathReference) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) SingularAttribute(javax.persistence.metamodel.SingularAttribute) Attribute(javax.persistence.metamodel.Attribute) ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) PluralAttribute(javax.persistence.metamodel.PluralAttribute) PluralAttribute(javax.persistence.metamodel.PluralAttribute) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) EmbeddableType(javax.persistence.metamodel.EmbeddableType) AbstractMap(java.util.AbstractMap) SingularAttribute(javax.persistence.metamodel.SingularAttribute) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) AbstractMap(java.util.AbstractMap)

Example 9 with ExtendedAttribute

use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.

the class Issue1436Test method testBuild.

@Test
public void testBuild() {
    ExtendedAttribute attribute = cbf.getService(EntityMetamodel.class).getManagedType(ExtendedManagedType.class, OrderItem.class).getAttribute("item.id1");
    assertEquals(1, attribute.getColumnNames().length);
}
Also used : ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) Test(org.junit.Test)

Example 10 with ExtendedAttribute

use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.

the class AbstractCommonQueryBuilder method fromValues.

public BuilderType fromValues(Class<?> valueClass, String alias, int valueCount) {
    ManagedType<?> type = mainQuery.metamodel.getManagedType(valueClass);
    if (type == null) {
        String sqlType = mainQuery.dbmsDialect.getSqlType(valueClass);
        if (sqlType == null) {
            throw new IllegalArgumentException("The basic type " + valueClass.getSimpleName() + " has no column type registered in the DbmsDialect '" + mainQuery.dbmsDialect.getClass().getName() + "'! Register a column type or consider using the fromValues variant that extracts column types from entity attributes!");
        }
        String typeName = cbf.getNamedTypes().get(valueClass);
        if (typeName == null) {
            throw new IllegalArgumentException("Unsupported non-managed type for VALUES clause: " + valueClass.getName() + ". You can register the type via com.blazebit.persistence.spi.CriteriaBuilderConfiguration.registerNamedType. Please report this so that we can add the type definition as well!");
        }
        String castedParameter = mainQuery.dbmsDialect.cast("?", sqlType);
        ExtendedAttribute valuesLikeAttribute = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, ValuesEntity.class).getAttribute("value");
        prepareFromModification();
        joinManager.addRootValues(ValuesEntity.class, valueClass, alias, valueCount, typeName, castedParameter, false, true, "value", valuesLikeAttribute, null, null);
    } else if (type instanceof EntityType<?>) {
        prepareFromModification();
        joinManager.addRootValues(valueClass, valueClass, alias, valueCount, null, null, false, true, null, null, null, null);
    } else {
        ExtendedManagedType<?> extendedManagedType = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, valueClass);
        Map.Entry<? extends EntityType<?>, String> entry = extendedManagedType.getEmbeddableSingularOwner();
        boolean singular = true;
        if (entry == null) {
            singular = false;
            entry = extendedManagedType.getEmbeddablePluralOwner();
        }
        if (entry == null) {
            throw new IllegalArgumentException("Unsupported use of embeddable type [" + valueClass + "] for values clause! Use the entity type and fromIdentifiableValues instead or introduce a CTE entity containing just the embeddable to be able to query it!");
        }
        Class<?> valueHolderEntityClass = entry.getKey().getJavaType();
        String valuesLikeAttributeName = entry.getValue();
        ExtendedAttribute valuesLikeAttribute = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, valueHolderEntityClass).getAttribute(valuesLikeAttributeName);
        prepareFromModification();
        joinManager.addRootValues(valueHolderEntityClass, valueClass, alias, valueCount, null, null, false, singular, valuesLikeAttributeName, valuesLikeAttribute, null, null);
    }
    fromClassExplicitlySet = true;
    return (BuilderType) this;
}
Also used : EntityType(javax.persistence.metamodel.EntityType) ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ValuesEntity(com.blazebit.persistence.impl.function.entity.ValuesEntity) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType)

Aggregations

ExtendedAttribute (com.blazebit.persistence.spi.ExtendedAttribute)21 ExtendedManagedType (com.blazebit.persistence.spi.ExtendedManagedType)13 Map (java.util.Map)7 PathExpression (com.blazebit.persistence.parser.expression.PathExpression)5 HashMap (java.util.HashMap)5 ArrayList (java.util.ArrayList)4 Attribute (javax.persistence.metamodel.Attribute)4 PluralAttribute (javax.persistence.metamodel.PluralAttribute)4 PathReference (com.blazebit.persistence.parser.expression.PathReference)3 EntityMetamodel (com.blazebit.persistence.parser.EntityMetamodel)2 ArrayExpression (com.blazebit.persistence.parser.expression.ArrayExpression)2 Expression (com.blazebit.persistence.parser.expression.Expression)2 FunctionExpression (com.blazebit.persistence.parser.expression.FunctionExpression)2 MapKeyExpression (com.blazebit.persistence.parser.expression.MapKeyExpression)2 NullExpression (com.blazebit.persistence.parser.expression.NullExpression)2 ParameterExpression (com.blazebit.persistence.parser.expression.ParameterExpression)2 PropertyExpression (com.blazebit.persistence.parser.expression.PropertyExpression)2 IdentityHashMap (java.util.IdentityHashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2