You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2025/09/23 02:50:02 UTC
(openjpa) 02/03: [WIP][OPENJPA-2940] Fixing Criteria typecast support when target type is a number
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 <pc...@gmail.com>
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");