diff --git a/core/api/src/main/java/com/blazebit/persistence/spi/JpaProvider.java b/core/api/src/main/java/com/blazebit/persistence/spi/JpaProvider.java
index fc56ad9b24..3eb50dd462 100644
--- a/core/api/src/main/java/com/blazebit/persistence/spi/JpaProvider.java
+++ b/core/api/src/main/java/com/blazebit/persistence/spi/JpaProvider.java
@@ -511,15 +511,6 @@ public interface JpaProvider {
*/
public boolean supportsTransientEntityAsParameter();
- /**
- * Indicates if the provider needs associations in the ON clause to use their id.
- * If needed, an expression like alias.association
in the ON clause is rewritten to
- * alias.association.id
.
- *
- * @return true if required, else false
- */
- public boolean needsAssociationToIdRewriteInOnClause();
-
/**
* Indicates if the provider needs associations in the ON clause to use their id.
* If needed, an expression like alias.association
in the ON clause is rewritten to
diff --git a/core/impl/src/main/java/com/blazebit/persistence/impl/AbstractUpdateCollectionCriteriaBuilder.java b/core/impl/src/main/java/com/blazebit/persistence/impl/AbstractUpdateCollectionCriteriaBuilder.java
index 41543c1e41..c4e80c8a5a 100644
--- a/core/impl/src/main/java/com/blazebit/persistence/impl/AbstractUpdateCollectionCriteriaBuilder.java
+++ b/core/impl/src/main/java/com/blazebit/persistence/impl/AbstractUpdateCollectionCriteriaBuilder.java
@@ -305,7 +305,7 @@ protected void prepareAndCheck(JoinVisitor parentVisitor) {
if (!needsCheck) {
return;
}
- boolean enableElementCollectionIdCutoff = collectionAttribute.getJoinTable() != null && !mainQuery.jpaProvider.needsAssociationToIdRewriteInOnClause();
+ boolean enableElementCollectionIdCutoff = collectionAttribute.getJoinTable() != null;
JpaUtils.expandBindings(setAttributeBindingMap, collectionColumnBindingMap, collectionAttributeEntries, ClauseType.SET, this, keyFunctionExpression, enableElementCollectionIdCutoff);
super.prepareAndCheck(parentVisitor);
}
diff --git a/core/impl/src/main/java/com/blazebit/persistence/impl/CachingJpaProvider.java b/core/impl/src/main/java/com/blazebit/persistence/impl/CachingJpaProvider.java
index 40dcd1b8df..b5055ab0cf 100644
--- a/core/impl/src/main/java/com/blazebit/persistence/impl/CachingJpaProvider.java
+++ b/core/impl/src/main/java/com/blazebit/persistence/impl/CachingJpaProvider.java
@@ -333,11 +333,6 @@ public boolean supportsTransientEntityAsParameter() {
return jpaProvider.supportsTransientEntityAsParameter();
}
- @Override
- public boolean needsAssociationToIdRewriteInOnClause() {
- return jpaProvider.needsAssociationToIdRewriteInOnClause();
- }
-
@Override
public boolean needsBrokenAssociationToIdRewriteInOnClause() {
return jpaProvider.needsBrokenAssociationToIdRewriteInOnClause();
diff --git a/core/impl/src/main/java/com/blazebit/persistence/impl/ResolvingQueryGenerator.java b/core/impl/src/main/java/com/blazebit/persistence/impl/ResolvingQueryGenerator.java
index de2842bff7..2eec5c940e 100644
--- a/core/impl/src/main/java/com/blazebit/persistence/impl/ResolvingQueryGenerator.java
+++ b/core/impl/src/main/java/com/blazebit/persistence/impl/ResolvingQueryGenerator.java
@@ -292,7 +292,9 @@ protected boolean isSimpleSubquery(SubqueryExpression expression) {
final boolean hasLimit = hasFirstResult || hasMaxResults;
final boolean hasSetOperations = subquery instanceof BaseFinalSetOperationBuilder, ?>;
final boolean hasEntityFunctions = subquery.joinManager.hasEntityFunctions();
- return !hasLimit && !hasSetOperations && !hasEntityFunctions && !subquery.joinManager.hasLateInlineNodes();
+ return (jpaProvider.supportsSubqueryLimitOffset() || !hasLimit)
+ && (jpaProvider.supportsSetOperations() || !hasSetOperations)
+ && !hasEntityFunctions && !subquery.joinManager.hasLateInlineNodes();
}
return super.isSimpleSubquery(expression);
}
@@ -885,37 +887,22 @@ public void visit(ArrayExpression expression) {
public void visit(InPredicate predicate) {
boolean quantifiedPredicate = this.quantifiedPredicate;
this.quantifiedPredicate = true;
- if (predicate.getRight().size() == 1 && jpaProvider.needsAssociationToIdRewriteInOnClause() && clauseType == ClauseType.JOIN) {
- Expression right = predicate.getRight().get(0);
- if (right instanceof ParameterExpression) {
- ParameterExpression parameterExpression = (ParameterExpression) right;
- @SuppressWarnings("unchecked")
- Type> associationType = getAssociationType(predicate.getLeft(), right);
- // If the association type is a entity type, we transform it
- if (associationType instanceof EntityType>) {
- renderEquality(predicate.getLeft(), right, predicate.isNegated(), PredicateQuantifier.ONE);
- } else {
- super.visit(predicate);
- }
- } else if (right instanceof PathExpression) {
- renderEquality(predicate.getLeft(), right, predicate.isNegated(), PredicateQuantifier.ONE);
- } else {
- super.visit(predicate);
- }
+ Expression right;
+ SubqueryExpression subqueryExpression;
+ if (!externalRepresentation
+ && predicate.getRight().size() == 1 && (right = predicate.getRight().get(0)) instanceof SubqueryExpression
+ && (subqueryExpression = (SubqueryExpression) right).getSubquery() instanceof SubqueryInternalBuilder>
+ && ((SubqueryInternalBuilder>) subqueryExpression.getSubquery()).getMaxResults() == 1) {
+ // This is a special rewrite for databases like e.g. MySQL
+ predicate.getLeft().accept(this);
+ sb.append(predicate.isNegated() ? " <> " : " = ");
+ right.accept(this);
} else {
super.visit(predicate);
}
this.quantifiedPredicate = quantifiedPredicate;
}
- private Type> getAssociationType(Expression expression1, Expression expression2) {
- if (expression1 instanceof PathExpression) {
- return ((PathExpression) expression1).getPathReference().getType();
- }
-
- return ((PathExpression) expression2).getPathReference().getType();
- }
-
@Override
public void visit(final EqPredicate predicate) {
boolean quantifiedPredicate = this.quantifiedPredicate;
@@ -938,60 +925,47 @@ private void renderEquality(Expression left, Expression right, boolean negated,
Expression expressionToSplit = needsEmbeddableSplitting(left, right);
- if (jpaProvider.needsAssociationToIdRewriteInOnClause() && clauseType == ClauseType.JOIN) {
- boolean rewritten = renderAssociationIdIfPossible(left);
+ if (expressionToSplit == null || !(left instanceof ParameterExpression) && !(right instanceof ParameterExpression)) {
+ left.accept(this);
sb.append(operator);
if (quantifier != PredicateQuantifier.ONE) {
sb.append(quantifier.toString());
}
- rewritten |= renderAssociationIdIfPossible(right);
- if (rewritten) {
- rewriteToIdParam(left);
- rewriteToIdParam(right);
- }
+ right.accept(this);
} else {
- if (expressionToSplit == null || !(left instanceof ParameterExpression) && !(right instanceof ParameterExpression)) {
- left.accept(this);
- sb.append(operator);
- if (quantifier != PredicateQuantifier.ONE) {
- sb.append(quantifier.toString());
- }
- right.accept(this);
+ // We split the path and the parameter expression accordingly
+ // TODO: Try to handle map key expressions, although no JPA provider supports de-referencing map keys
+ PathExpression pathExpression = (PathExpression) expressionToSplit;
+ ParameterExpression parameterExpression;
+ if (left instanceof ParameterExpression) {
+ parameterExpression = (ParameterExpression) left;
} else {
- // We split the path and the parameter expression accordingly
- // TODO: Try to handle map key expressions, although no JPA provider supports de-referencing map keys
- PathExpression pathExpression = (PathExpression) expressionToSplit;
- ParameterExpression parameterExpression;
- if (left instanceof ParameterExpression) {
- parameterExpression = (ParameterExpression) left;
- } else {
- parameterExpression = (ParameterExpression) right;
+ parameterExpression = (ParameterExpression) right;
+ }
+ PathReference pathReference = pathExpression.getPathReference();
+ EmbeddableType> embeddableType = (EmbeddableType>) pathReference.getType();
+ String parameterName = parameterExpression.getName();
+ Map> parameterAccessPaths = new HashMap<>();
+ ParameterManager.ParameterImpl> parameter = parameterManager.getParameter(parameterName);
+ sb.append('(');
+ for (Attribute, ?> attribute : embeddableType.getAttributes()) {
+ ((JoinNode) pathReference.getBaseNode()).appendDeReference(sb, pathReference.getField() + "." + attribute.getName(), externalRepresentation);
+ String embeddedPropertyName = attribute.getName();
+ String subParamName = "_" + parameterName + "_" + embeddedPropertyName.replace('.', '_');
+ sb.append(operator);
+ sb.append(":").append(subParamName);
+ if (parameter.getTransformer() == null) {
+ parameterManager.registerParameterName(subParamName, false, null, null);
}
- PathReference pathReference = pathExpression.getPathReference();
- EmbeddableType> embeddableType = (EmbeddableType>) pathReference.getType();
- String parameterName = parameterExpression.getName();
- Map> parameterAccessPaths = new HashMap<>();
- ParameterManager.ParameterImpl> parameter = parameterManager.getParameter(parameterName);
- sb.append('(');
- for (Attribute, ?> attribute : embeddableType.getAttributes()) {
- ((JoinNode) pathReference.getBaseNode()).appendDeReference(sb, pathReference.getField() + "." + attribute.getName(), externalRepresentation);
- String embeddedPropertyName = attribute.getName();
- String subParamName = "_" + parameterName + "_" + embeddedPropertyName.replace('.', '_');
- sb.append(operator);
- sb.append(":").append(subParamName);
- if (parameter.getTransformer() == null) {
- parameterManager.registerParameterName(subParamName, false, null, null);
- }
- parameterAccessPaths.put(subParamName, Arrays.asList(embeddedPropertyName.split("\\.")));
+ parameterAccessPaths.put(subParamName, Arrays.asList(embeddedPropertyName.split("\\.")));
- sb.append(" AND ");
- }
- sb.setLength(sb.length() - " AND ".length());
- sb.append(')');
+ sb.append(" AND ");
+ }
+ sb.setLength(sb.length() - " AND ".length());
+ sb.append(')');
- if (parameter.getTransformer() == null) {
- parameter.setTransformer(new SplittingParameterTransformer(parameterManager, entityMetamodel, embeddableType.getJavaType(), parameterAccessPaths));
- }
+ if (parameter.getTransformer() == null) {
+ parameter.setTransformer(new SplittingParameterTransformer(parameterManager, entityMetamodel, embeddableType.getJavaType(), parameterAccessPaths));
}
}
setBooleanLiteralRenderingContext(oldBooleanLiteralRenderingContext);
diff --git a/integration/eclipselink/src/main/java/com/blazebit/persistence/integration/eclipselink/EclipseLinkJpaProvider.java b/integration/eclipselink/src/main/java/com/blazebit/persistence/integration/eclipselink/EclipseLinkJpaProvider.java
index c4e97021e5..cf15438598 100644
--- a/integration/eclipselink/src/main/java/com/blazebit/persistence/integration/eclipselink/EclipseLinkJpaProvider.java
+++ b/integration/eclipselink/src/main/java/com/blazebit/persistence/integration/eclipselink/EclipseLinkJpaProvider.java
@@ -618,11 +618,6 @@ public boolean supportsTransientEntityAsParameter() {
return true;
}
- @Override
- public boolean needsAssociationToIdRewriteInOnClause() {
- return false;
- }
-
@Override
public boolean needsBrokenAssociationToIdRewriteInOnClause() {
return false;
diff --git a/integration/hibernate6-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java b/integration/hibernate6-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java
index 93fe562d99..2d5ae35992 100644
--- a/integration/hibernate6-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java
+++ b/integration/hibernate6-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateJpaProvider.java
@@ -129,11 +129,6 @@ public boolean supportsForeignAssociationInOnClause() {
return true;
}
- @Override
- public boolean needsAssociationToIdRewriteInOnClause() {
- return false;
- }
-
@Override
public boolean needsBrokenAssociationToIdRewriteInOnClause() {
return false;