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();
}
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();
}
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);
}
}
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;
}
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;
}
Aggregations