Search in sources :

Example 11 with ExtendedManagedType

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

the class CachingJpaProvider method hasJoinCondition.

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

Example 12 with ExtendedManagedType

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

the class CachingJpaProvider method isOrphanRemoval.

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

Example 13 with ExtendedManagedType

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

the class SelectManager method buildSelectItems.

void buildSelectItems(StringBuilder sb, boolean isInsertInto, boolean externalRepresentation, boolean renderAlias) {
    List<SelectInfo> infos = selectInfos;
    int size = infos.size();
    ExtendedManagedType<?> managedType;
    if (size == 0) {
        JoinNode rootNode = joinManager.getRootNodeOrFail("Empty select not allowed when having multiple roots!");
        if (!externalRepresentation && queryBuilder instanceof SubqueryBuilder<?> && rootNode.getType() instanceof IdentifiableType<?> && !mainQuery.jpaProvider.supportsSelectCompositeIdEntityInSubquery() && hasCompositeId(managedType = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, rootNode.getManagedType()))) {
            emulateSelectCompositeId(sb, rootNode, managedType);
        } else {
            rootNode.appendAlias(sb, externalRepresentation);
        }
    } else {
        // we must not replace select alias since we would loose the original expressions
        queryGenerator.setClauseType(ClauseType.SELECT);
        queryGenerator.setQueryBuffer(sb);
        SimpleQueryGenerator.BooleanLiteralRenderingContext oldBooleanLiteralRenderingContext = queryGenerator.setBooleanLiteralRenderingContext(SimpleQueryGenerator.BooleanLiteralRenderingContext.CASE_WHEN);
        SimpleQueryGenerator.ParameterRenderingMode oldParameterRenderingMode;
        if (!mainQuery.getQueryConfiguration().isParameterAsLiteralRenderingEnabled() || isInsertInto) {
            // Insert into supports parameters
            oldParameterRenderingMode = queryGenerator.setParameterRenderingMode(SimpleQueryGenerator.ParameterRenderingMode.PLACEHOLDER);
        } else {
            oldParameterRenderingMode = queryGenerator.setParameterRenderingMode(SimpleQueryGenerator.ParameterRenderingMode.LITERAL);
        }
        PathExpression pathExpression;
        if (!externalRepresentation && queryBuilder instanceof SubqueryBuilder<?> && size == 1 && !mainQuery.jpaProvider.supportsSelectCompositeIdEntityInSubquery() && infos.get(0).getExpression() instanceof PathExpression && (pathExpression = (PathExpression) infos.get(0).getExpression()).getPathReference().getType() instanceof IdentifiableType<?> && hasCompositeId(managedType = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, (ManagedType<?>) pathExpression.getPathReference().getType()))) {
            emulateSelectCompositeId(sb, (JoinNode) pathExpression.getBaseNode(), managedType);
        } else {
            for (int i = 0; i < size; i++) {
                if (i != 0) {
                    sb.append(", ");
                }
                applySelect(queryGenerator, sb, infos.get(i), renderAlias);
            }
        }
        queryGenerator.setBooleanLiteralRenderingContext(oldBooleanLiteralRenderingContext);
        queryGenerator.setParameterRenderingMode(oldParameterRenderingMode);
        queryGenerator.setClauseType(null);
    }
}
Also used : ManagedType(javax.persistence.metamodel.ManagedType) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) IdentifiableType(javax.persistence.metamodel.IdentifiableType) SubqueryBuilder(com.blazebit.persistence.SubqueryBuilder) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) SimpleQueryGenerator(com.blazebit.persistence.parser.SimpleQueryGenerator)

Example 14 with ExtendedManagedType

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

the class JoinManager method renderCorrelationJoinPath.

private boolean renderCorrelationJoinPath(StringBuilder sb, JoinNode joinBase, JoinNode node, String correlationPath, List<String> whereConjuncts, List<String> optionalWhereConjuncts, boolean externalRepresentation) {
    JoinAliasInfo joinBaseAliasInfo = joinBase.getAliasInfo();
    StringBuilder whereSb = null;
    if (node.getJoinNodesNeedingTreatConjunct() != null) {
        whereSb = new StringBuilder();
        for (JoinNode joinNode : node.getJoinNodesNeedingTreatConjunct()) {
            whereSb.setLength(0);
            whereSb.append("TYPE(");
            joinNode.appendAlias(whereSb, false, externalRepresentation);
            whereSb.append(") = ");
            whereSb.append(joinNode.getTreatType().getName());
            whereConjuncts.add(whereSb.toString());
        }
    }
    final boolean renderTreat = mainQuery.jpaProvider.supportsTreatJoin() && (!mainQuery.jpaProvider.supportsSubtypeRelationResolving() || node.getJoinType() == JoinType.INNER);
    if (mainQuery.jpaProvider.needsCorrelationPredicateWhenCorrelatingWithWhereClause() || node.getTreatType() != null && !renderTreat && !mainQuery.jpaProvider.supportsSubtypeRelationResolving()) {
        ExtendedManagedType<?> extendedManagedType = metamodel.getManagedType(ExtendedManagedType.class, joinBase.getManagedType());
        ExtendedAttribute attribute = extendedManagedType.getAttribute(correlationPath);
        if (StringUtils.isEmpty(attribute.getMappedBy())) {
            if (attribute.getAttribute() instanceof ListAttribute<?, ?> && !attribute.isBag()) {
                // What the hell Hibernate? Why just for indexed lists?
                sb.append(joinBase.getEntityType().getName());
                sb.append(" _synthetic_");
                sb.append(node.getAlias());
                sb.append(" JOIN _synthetic_");
                sb.append(node.getAlias());
                sb.append('.').append(correlationPath);
                if (whereSb == null) {
                    whereSb = new StringBuilder();
                } else {
                    whereSb.setLength(0);
                }
                whereSb.append("_synthetic_").append(node.getAlias());
                boolean singleValuedAssociationId = mainQuery.jpaProvider.supportsSingleValuedAssociationIdExpressions() && extendedManagedType.getIdAttributes().size() == 1;
                if (singleValuedAssociationId) {
                    whereSb.append('.').append(extendedManagedType.getIdAttribute().getName());
                }
                whereSb.append(" = ");
                joinBase.appendAlias(whereSb, false, externalRepresentation);
                if (singleValuedAssociationId) {
                    whereSb.append('.').append(extendedManagedType.getIdAttribute().getName());
                }
                whereConjuncts.add(whereSb.toString());
                return true;
            }
        } else {
            boolean renderAlias = true;
            sb.append(node.getEntityType().getName());
            if (whereSb == null) {
                whereSb = new StringBuilder();
            } else {
                whereSb.setLength(0);
            }
            ExtendedManagedType elementManagedType = metamodel.getManagedType(ExtendedManagedType.class, node.getManagedType());
            if (elementManagedType.getAttribute(attribute.getMappedBy()).getAttribute().isCollection()) {
                renderAlias = false;
                sb.append(' ');
                sb.append(node.getAlias());
                sb.append(" JOIN ");
                sb.append(node.getAlias());
                sb.append('.').append(attribute.getMappedBy());
                sb.append(" _synthetic_");
                sb.append(node.getAlias());
                whereSb.append(" _synthetic_").append(node.getAlias());
            } else {
                whereSb.append(node.getAlias());
                whereSb.append('.').append(attribute.getMappedBy());
            }
            boolean singleValuedAssociationId = mainQuery.jpaProvider.supportsSingleValuedAssociationIdExpressions() && extendedManagedType.getIdAttributes().size() == 1;
            if (singleValuedAssociationId) {
                whereSb.append('.').append(extendedManagedType.getIdAttribute().getName());
            }
            whereSb.append(" = ");
            joinBase.appendAlias(whereSb, false, externalRepresentation);
            if (singleValuedAssociationId) {
                whereSb.append('.').append(extendedManagedType.getIdAttribute().getName());
            }
            whereConjuncts.add(whereSb.toString());
            return renderAlias;
        }
    }
    if (node.getTreatType() != null) {
        if (renderTreat) {
            sb.append("TREAT(");
            renderAlias(sb, joinBaseAliasInfo.getJoinNode(), mainQuery.jpaProvider.supportsRootTreat(), externalRepresentation);
            sb.append('.');
            sb.append(correlationPath);
            sb.append(" AS ");
            sb.append(node.getTreatType().getName());
            sb.append(')');
        } else if (mainQuery.jpaProvider.supportsSubtypeRelationResolving()) {
            joinBaseAliasInfo.getJoinNode().appendAlias(sb, false, externalRepresentation);
            sb.append('.').append(correlationPath);
        } else {
            throw new IllegalArgumentException("Treat should not be used as the JPA provider does not support subtype property access!");
        }
    } else {
        JoinNode baseNode = joinBaseAliasInfo.getJoinNode();
        if (baseNode.getTreatType() != null) {
            if (mainQuery.jpaProvider.supportsRootTreatJoin()) {
                baseNode.appendAlias(sb, true, externalRepresentation);
            } else if (mainQuery.jpaProvider.supportsSubtypeRelationResolving()) {
                baseNode.appendAlias(sb, false, externalRepresentation);
            } else {
                throw new IllegalArgumentException("Treat should not be used as the JPA provider does not support subtype property access!");
            }
        } else {
            baseNode.appendAlias(sb, false, externalRepresentation);
        }
        sb.append('.').append(correlationPath);
    }
    return true;
}
Also used : ExtendedAttribute(com.blazebit.persistence.spi.ExtendedAttribute) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType)

Example 15 with ExtendedManagedType

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

the class JoinManager method isSingleValuedAssociationId.

private boolean isSingleValuedAssociationId(JoinNode current, PathExpression currentPathExpression, int start) {
    ExtendedManagedType<?> extendedManagedType = metamodel.getManagedType(ExtendedManagedType.class, current.getManagedType());
    // Only if all path elements are property expressions, we check if this is single valued association id
    List<PathElementExpression> expressions = currentPathExpression.getExpressions();
    int size = expressions.size() - start;
    List<PathElementExpression> pathElements = new ArrayList<>(size);
    for (int i = start; i < expressions.size(); i++) {
        PathElementExpression pathElementExpression = expressions.get(i);
        if (pathElementExpression instanceof PropertyExpression) {
            pathElements.add(pathElementExpression);
        } else {
            return false;
        }
    }
    PathExpression pathRestExpression = new PathExpression(pathElements);
    String pathRestString = pathRestExpression.toString();
    int idx = 0;
    ExtendedAttribute<?, ?> extendedAttribute;
    if (current.getValuesLikeAttribute() == null) {
        extendedAttribute = extendedManagedType.getOwnedSingularAttributes().get(pathRestString);
    } else {
        extendedAttribute = extendedManagedType.getAttributes().get(pathRestString);
    }
    if (extendedAttribute != null && !JpaMetamodelUtils.isAssociation(extendedAttribute.getAttribute())) {
        ExtendedAttribute<?, ?> associationAttribute = null;
        ExtendedAttribute<?, ?> attr;
        int singleValuedAssociationNameEndIndex = -1;
        List<String> newResultFields = new ArrayList<>();
        for (int j = 0; j < pathElements.size(); j++) {
            idx = pathRestString.indexOf('.', idx + 1);
            if (idx != -1 && JpaMetamodelUtils.isAssociation((attr = extendedManagedType.getAttribute(pathRestString.substring(0, idx))).getAttribute())) {
                associationAttribute = attr;
                singleValuedAssociationNameEndIndex = j;
            }
            newResultFields.add(pathElements.get(j).toString());
        }
        if (associationAttribute == null) {
            return false;
        } else if (current.getValueType() == null && mainQuery.jpaProvider.isForeignJoinColumn((EntityType<?>) current.getManagedType(), new PathExpression(pathElements.subList(0, singleValuedAssociationNameEndIndex + 1)).toString()) || current.getValueType() != null && mainQuery.jpaProvider.isForeignJoinColumn(current.getValueType(), current.getValuesLikeAttribute() + "." + new PathExpression(pathElements.subList(0, singleValuedAssociationNameEndIndex + 1)).toString())) {
            // If the column is "foreign", we can't do any optimizations
            return false;
        } else if (!mainQuery.jpaProvider.supportsSingleValuedAssociationNaturalIdExpressions() && !contains(metamodel.getManagedType(ExtendedManagedType.class, associationAttribute.getElementClass()), new PathExpression(pathElements.subList(singleValuedAssociationNameEndIndex + 1, size)))) {
            // If the jpa provider doesn't support any optimizations, we are done
            return false;
        } else {
            return true;
        }
    }
    return false;
}
Also used : EntityType(javax.persistence.metamodel.EntityType) PathElementExpression(com.blazebit.persistence.parser.expression.PathElementExpression) PathExpression(com.blazebit.persistence.parser.expression.PathExpression) ArrayList(java.util.ArrayList) PropertyExpression(com.blazebit.persistence.parser.expression.PropertyExpression) ExtendedManagedType(com.blazebit.persistence.spi.ExtendedManagedType)

Aggregations

ExtendedManagedType (com.blazebit.persistence.spi.ExtendedManagedType)20 ExtendedAttribute (com.blazebit.persistence.spi.ExtendedAttribute)13 EntityType (javax.persistence.metamodel.EntityType)8 PathExpression (com.blazebit.persistence.parser.expression.PathExpression)7 ManagedType (javax.persistence.metamodel.ManagedType)7 HashMap (java.util.HashMap)6 Map (java.util.Map)6 EntityMetamodel (com.blazebit.persistence.parser.EntityMetamodel)5 ArrayList (java.util.ArrayList)4 Attribute (javax.persistence.metamodel.Attribute)4 EmbeddableType (javax.persistence.metamodel.EmbeddableType)4 SingularAttribute (javax.persistence.metamodel.SingularAttribute)4 PathReference (com.blazebit.persistence.parser.expression.PathReference)3 LinkedHashMap (java.util.LinkedHashMap)3 MapKeyExpression (com.blazebit.persistence.parser.expression.MapKeyExpression)2 PathElementExpression (com.blazebit.persistence.parser.expression.PathElementExpression)2 PropertyExpression (com.blazebit.persistence.parser.expression.PropertyExpression)2 JpaProvider (com.blazebit.persistence.spi.JpaProvider)2 InverseRemoveStrategy (com.blazebit.persistence.view.InverseRemoveStrategy)2 AttributeAccessor (com.blazebit.persistence.view.impl.accessor.AttributeAccessor)2