This is an automated email from the ASF dual-hosted git repository. pcristof pushed a commit to branch OPENJPA-2940 in repository https://gitbox.apache.org/repos/asf/openjpa.git
commit f06c2231fe8095d7cdf0440f785217dfcd62379e Author: Paulo Cristovão de Araújo Silva Filho <[email protected]> AuthorDate: Mon Sep 22 11:34:09 2025 -0300 [WIP][OPENJPA-2940] Fixing Criteria typecast support when target type is a number --- .../criteria/TestTypecastAsCriteria.java | 11 +++++------ .../persistence/criteria/ExpressionImpl.java | 8 ++++---- .../openjpa/persistence/criteria/Expressions.java | 22 ++++++++++++++++++++-- .../openjpa/persistence/criteria/PathImpl.java | 8 ++++---- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypecastAsCriteria.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypecastAsCriteria.java index 716107259..b342fecbf 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypecastAsCriteria.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/criteria/TestTypecastAsCriteria.java @@ -52,11 +52,11 @@ public class TestTypecastAsCriteria extends CriteriaTest { } public void testTypecastAsInteger() { - String jpql = "SELECT c FROM Customer c JOIN c.orders o WHERE CAST(o.quantity AS INTEGER) = 0"; + String jpql = "SELECT c FROM Customer c JOIN c.orders o WHERE CAST(CAST(o.quantity AS STRING) AS INTEGER) = 0"; CriteriaQuery<Customer> q = cb.createQuery(Customer.class); Root<Customer> c = q.from(Customer.class); SetJoin<Customer, Order> o = c.joinSet("orders"); - q.where(cb.equal(o.get("quantity").cast(Integer.class), 0)); + q.where(cb.equal(o.get("quantity").cast(String.class).cast(Integer.class), 0)); q.select(c); assertEquivalence(q, jpql); @@ -67,7 +67,7 @@ public class TestTypecastAsCriteria extends CriteriaTest { CriteriaQuery<Customer> q = cb.createQuery(Customer.class); Root<Customer> c = q.from(Customer.class); SetJoin<Customer, Order> o = c.joinSet("orders"); - q.where(cb.equal(o.get("quantity").cast(Long.class), 0l)); + q.where(cb.equal(o.get("quantity").cast(String.class).cast(Long.class), 0l)); q.select(c); assertEquivalence(q, jpql); @@ -78,7 +78,7 @@ public class TestTypecastAsCriteria extends CriteriaTest { CriteriaQuery<Customer> q = cb.createQuery(Customer.class); Root<Customer> c = q.from(Customer.class); SetJoin<Customer, Order> o = c.joinSet("orders"); - q.where(cb.equal(o.get("quantity").cast(Float.class), 0f)); + q.where(cb.equal(o.get("quantity").cast(String.class).cast(Float.class), 0f)); q.select(c); assertEquivalence(q, jpql); @@ -89,14 +89,13 @@ public class TestTypecastAsCriteria extends CriteriaTest { CriteriaQuery<Customer> q = cb.createQuery(Customer.class); Root<Customer> c = q.from(Customer.class); SetJoin<Customer, Order> o = c.joinSet("orders"); - q.where(cb.equal(o.get("quantity").cast(Float.class), 0d)); + q.where(cb.equal(o.get("quantity").cast(String.class).cast(Double.class), 0d)); q.select(c); assertEquivalence(q, jpql); } public void testTypecastAsInvalid() { - String jpql = "SELECT c FROM Customer c JOIN c.orders o WHERE CAST(o.quantity AS double) = 0"; CriteriaQuery<Customer> q = cb.createQuery(Customer.class); Root<Customer> c = q.from(Customer.class); SetJoin<Customer, Order> o = c.joinSet("orders"); diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java index 32dcc2917..2c413cf2e 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/ExpressionImpl.java @@ -129,13 +129,13 @@ public Predicate in(Object... values) { public <X> Expression<X> cast(Class<X> type) { if (type == String.class) { return new Expressions.TypecastAs(this, "STRING"); - } else if (type == Integer.class) { + } else if (type == Integer.class || type == int.class) { return new Expressions.TypecastAs(this, "INTEGER"); - } else if (type == Long.class) { + } else if (type == Long.class || type == long.class) { return new Expressions.TypecastAs(this, "LONG"); - } else if (type == Float.class) { + } else if (type == Float.class || type == float.class) { return new Expressions.TypecastAs(this, "FLOAT"); - } else if (type == Double.class) { + } else if (type == Double.class || type == double.class) { return new Expressions.TypecastAs(this, "DOUBLE"); } throw new IllegalArgumentException("Target cast not supported"); diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java index 7d30dc146..1e82c64f1 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/Expressions.java @@ -623,12 +623,30 @@ class Expressions { @Override public Value toValue(ExpressionFactory factory, CriteriaQueryImpl q) { - return factory.newTypecastAsString(Expressions.toValue(e, factory, q)); + return switch (target) { + case "STRING": { + yield factory.newTypecastAsString(Expressions.toValue(e, factory, q)); + } + case "INTEGER":{ + yield factory.newTypecastAsNumber(Expressions.toValue(e, factory, q), Integer.class); + } + case "LONG":{ + yield factory.newTypecastAsNumber(Expressions.toValue(e, factory, q), Long.class); + } + case "FLOAT":{ + yield factory.newTypecastAsNumber(Expressions.toValue(e, factory, q), Float.class); + } + case "DOUBLE":{ + yield factory.newTypecastAsNumber(Expressions.toValue(e, factory, q), Double.class); + } + default: + throw new IllegalArgumentException("Unexpected value: " + target); + }; } @Override public StringBuilder asValue(AliasContext q) { - return Expressions.asValue(q, "CAST", OPEN_BRACE, e, "AS", target, CLOSE_BRACE); + return Expressions.asValue(q, "CAST", OPEN_BRACE, e, " AS ", target, CLOSE_BRACE); } } diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java index 6f5ee0ed8..8dc92213e 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/criteria/PathImpl.java @@ -356,13 +356,13 @@ class PathImpl<Z,X> extends ExpressionImpl<X> implements Path<X> { public <X> Expression<X> cast(Class<X> type) { if (type == String.class) { return new Expressions.TypecastAs(this, "STRING"); - } else if (type == Integer.class) { + } else if (type == Integer.class || type == int.class) { return new Expressions.TypecastAs(this, "INTEGER"); - } else if (type == Long.class) { + } else if (type == Long.class || type == long.class) { return new Expressions.TypecastAs(this, "LONG"); - } else if (type == Float.class) { + } else if (type == Float.class || type == float.class) { return new Expressions.TypecastAs(this, "FLOAT"); - } else if (type == Double.class) { + } else if (type == Double.class || type == double.class) { return new Expressions.TypecastAs(this, "DOUBLE"); } throw new IllegalArgumentException("Target cast not supported");
