diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java index 6bdabbfd509..047d926a583 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java @@ -2618,7 +2618,7 @@ public void setArgumentIndices(int[] indices) { } /** - * Return the argumentIndices if set, otherwise initialize argumentIndices to the provided size + * Returns the argumentIndices if set, otherwise returns an array of indexes of the provided size. */ public int[] getArgumentIndices(int size) { int[] indices = this.argumentIndices; @@ -2630,7 +2630,11 @@ public int[] getArgumentIndices(int size) { for (int i = 0; i < indices.length; i++) { indices[i] = i; } - this.argumentIndices = indices; + + // NOTE: Why not cache the newly generated array of indexes like "this.argumentIndices = indices" here? + // The reason is that some operators have variable number of arguments like COALESCE and CASE WHEN. + // As instances of this class are shared between threads we cannot cache the array of indexes. + return indices; } diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/ArgumentListFunctionExpression.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/ArgumentListFunctionExpression.java index aef4bdd28f7..eff75d6393b 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/ArgumentListFunctionExpression.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/expressions/ArgumentListFunctionExpression.java @@ -97,10 +97,10 @@ public void setOperator(ExpressionOperator theOperator) { */ @Override public void printSQL(ExpressionSQLPrinter printer) { - ListExpressionOperator operator = (ListExpressionOperator) this.operator; - - operator.setIsComplete(true); - operator.printCollection(this.children, printer); + ListExpressionOperator realOperator = (ListExpressionOperator) getPlatformOperator(printer.getPlatform()); + operator.copyTo(realOperator); + realOperator.setIsComplete(true); + realOperator.printCollection(this.children, printer); } diff --git a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/jpql/TestArgumentListFunctionExpressionConcurrency.java b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/jpql/TestArgumentListFunctionExpressionConcurrency.java index 05c063efff4..c21bd6c35bc 100644 --- a/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/jpql/TestArgumentListFunctionExpressionConcurrency.java +++ b/jpa/eclipselink.jpa.test.jse/src/it/java/org/eclipse/persistence/jpa/test/jpql/TestArgumentListFunctionExpressionConcurrency.java @@ -47,11 +47,12 @@ public void testConcurrentUseOfCoalesce() throws Exception { runInParallel((em, i) -> { String jpql; if (i % 2 == 0) { - jpql = "SELECT p FROM JPQLEntity p WHERE p.string1 = coalesce(p.string2, p.string1, '" + cacheBuster(i) + "')"; - } else { jpql = "SELECT p FROM JPQLEntity p WHERE p.string1 = coalesce(p.string2, '" + cacheBuster(i) + "')"; + } else { + jpql = "SELECT p FROM JPQLEntity p WHERE p.string1 = coalesce(p.string2, p.string1, '" + cacheBuster(i) + "')"; } em.createQuery(jpql, JPQLEntity.class).getResultList(); + System.out.println(Thread.currentThread().getName() + " - " + i % 2); }); }