This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch merge-hibernate6
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit 21dec6b17bb91760dad5adf74846ed44ab2149f8
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Jun 21 21:54:31 2025 -0500

    Standalone JpaFromProvider
---
 .../hibernate/query/AbstractHibernateQuery.java    |  39 +++---
 .../orm/hibernate/query/JpaFromProvider.java       |  95 +++++++-------
 .../orm/hibernate/query/PredicateGenerator.java    | 139 ++++++++++-----------
 3 files changed, 129 insertions(+), 144 deletions(-)

diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java
index 9fedb54bed..f774635904 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/AbstractHibernateQuery.java
@@ -21,7 +21,6 @@ import jakarta.persistence.FetchType;
 import jakarta.persistence.criteria.CriteriaQuery;
 import jakarta.persistence.criteria.Expression;
 import jakarta.persistence.criteria.From;
-import jakarta.persistence.criteria.Join;
 import jakarta.persistence.criteria.JoinType;
 import jakarta.persistence.criteria.Path;
 import org.grails.datastore.gorm.query.criteria.DetachedAssociationCriteria;
@@ -45,7 +44,6 @@ import org.springframework.core.convert.ConversionService;
 import org.springframework.core.convert.support.DefaultConversionService;
 import org.springframework.dao.InvalidDataAccessApiUsageException;
 
-import java.util.AbstractMap;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -55,8 +53,6 @@ import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * Bridges the Query API with the Hibernate Criteria API
@@ -494,8 +490,8 @@ public abstract class AbstractHibernateQuery extends Query {
         var projectionList = collectProjections();
         var cq = createCriteriaQuery(projectionList);
         From root = cq.from(entity.getJavaClass());
-        var jpaFromProvider = new JpaFromProvider(detachedCriteria);
-        Map<String, From> tablesByName = jpaFromProvider.getFromsByName(cq, 
root);
+        var tablesByName = new JpaFromProvider(detachedCriteria,cq,root);
+
 
         assignProjections(projectionList, cq, tablesByName);
 
@@ -582,7 +578,7 @@ public abstract class AbstractHibernateQuery extends Query {
                 .toList();
     }
 
-    private void assignCriteria(CriteriaQuery cq, HibernateCriteriaBuilder cb, 
From root, Map<String, From> tablesByName) {
+    private void assignCriteria(CriteriaQuery cq, HibernateCriteriaBuilder cb, 
From root, JpaFromProvider tablesByName) {
         List<Criterion>  criteriaList = getDetachedCriteria();
         if (!criteriaList.isEmpty()) {
             jakarta.persistence.criteria.Predicate[] predicates = 
PredicateGenerator.getPredicates(cb, cq, root, criteriaList, tablesByName);
@@ -590,14 +586,14 @@ public abstract class AbstractHibernateQuery extends 
Query {
         }
     }
 
-    private void assignOrderBy(CriteriaQuery cq, Map<String, From> 
tablesByName) {
+    private void assignOrderBy(CriteriaQuery cq, JpaFromProvider tablesByName) 
{
         var cb = getCriteriaBuilder();
         List<Order> orders = detachedCriteria.getOrders();
         if (!orders.isEmpty()) {
             cq.orderBy(orders
                     .stream()
                     .map(order -> {
-                        Path expression = getFullyQualifiedPath(tablesByName, 
order.getProperty());
+                        Path expression = 
tablesByName.getFullyQualifiedPath(order.getProperty());
                         if (order.isIgnoreCase() && 
expression.getJavaType().equals(String.class)) {
                             if 
(order.getDirection().equals(Order.Direction.ASC)) {
                                 return cb.asc(cb.lower(expression));
@@ -618,13 +614,13 @@ public abstract class AbstractHibernateQuery extends 
Query {
         }
     }
 
-    private void assignGroupBy(List<GroupPropertyProjection> groupProjections, 
From root, CriteriaQuery cq, Map<String, From> tablesByName) {
+    private void assignGroupBy(List<GroupPropertyProjection> groupProjections, 
From root, CriteriaQuery cq, JpaFromProvider tablesByName) {
         if (!groupProjections.isEmpty()) {
             List<Expression> groupByPaths = groupProjections
                     .stream()
                     .map(groupPropertyProjection -> {
                         String propertyName = 
groupPropertyProjection.getPropertyName();
-                        return getFullyQualifiedPath(tablesByName, 
propertyName);
+                        return 
tablesByName.getFullyQualifiedPath(propertyName);
                     })
                     .map(Expression.class::cast)
                     .toList();
@@ -632,7 +628,7 @@ public abstract class AbstractHibernateQuery extends Query {
         }
     }
 
-    private void assignProjections(List<Projection> projections, CriteriaQuery 
cq, Map<String, From> tablesByName) {
+    private void assignProjections(List<Projection> projections, CriteriaQuery 
cq, JpaFromProvider tablesByName) {
         List<Expression> projectionExpressions = projections
                 .stream()
                 .map(projectionToJpaExpression(tablesByName))
@@ -644,26 +640,26 @@ public abstract class AbstractHibernateQuery extends 
Query {
         } else if (projectionExpressions.size() > 1){
             cq.multiselect(projectionExpressions);
         } else {
-            cq.select(tablesByName.get("root"));
+            cq.select(tablesByName.getFullyQualifiedPath("root"));
         }
     }
 
     private Function<Projection, JpaExpression> projectionToJpaExpression(
-            Map<String, From> tablesByName) {
+            JpaFromProvider tablesByName) {
         var cb = getCriteriaBuilder();
         return projection -> {
             if (countProjectionPredicate.test(projection)) {
-                return cb.count(tablesByName.get("root"));
+                return cb.count(tablesByName.getFullyQualifiedPath("root"));
             } else if (countDistinctProjection.test(projection)) {
                 String propertyName = ((PropertyProjection) 
projection).getPropertyName();
-                return 
cb.countDistinct(tablesByName.get("root").get(propertyName));
+                return 
cb.countDistinct(tablesByName.getFullyQualifiedPath("root." + propertyName));
             } else if (idProjectionPredicate.test(projection)) {
-                return (JpaExpression) tablesByName.get("root").get("id");
+                return (JpaExpression) 
tablesByName.getFullyQualifiedPath("root.id");
             } else if (distinctProjectionPredicate.test(projection)) {
                 return null;
             } else {
                 String propertyName = ((PropertyProjection) 
projection).getPropertyName();
-                Path path = getFullyQualifiedPath(tablesByName, propertyName);
+                Path path = tablesByName.getFullyQualifiedPath(propertyName);
                 if (maxProjectionPredicate.test(projection)) {
                     return cb.max(path);
                 } else if (minProjectionPredicate.test(projection)) {
@@ -680,13 +676,6 @@ public abstract class AbstractHibernateQuery extends Query 
{
         };
     }
 
-    public static Path getFullyQualifiedPath(Map<String, From> tablesByName, 
String propertyName) {
-        String[] parsed = propertyName.split("\\.");
-        String tableName = parsed.length > 1 ? parsed[0] : "root";
-        String columnName = parsed.length > 1 ? parsed[1] : propertyName;
-        return tablesByName.get(tableName).get(columnName);
-    }
-
     private SessionFactory getSessionFactory() {
         return ((IHibernateTemplate) 
session.getNativeInterface()).getSessionFactory();
     }
diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
index 8038900800..629ad2767e 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
@@ -3,12 +3,15 @@ package org.grails.orm.hibernate.query;
 import grails.gorm.DetachedCriteria;
 import jakarta.persistence.FetchType;
 import jakarta.persistence.criteria.From;
+import jakarta.persistence.criteria.Join;
 import jakarta.persistence.criteria.JoinType;
+import jakarta.persistence.criteria.Path;
 import org.grails.datastore.gorm.query.criteria.DetachedAssociationCriteria;
 import org.grails.datastore.mapping.query.Query;
 import org.hibernate.query.criteria.JpaCriteriaQuery;
 
 import java.util.AbstractMap;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -16,24 +19,44 @@ import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-public class JpaFromProvider {
+public class JpaFromProvider implements Cloneable {
 
-    private final DetachedCriteria detachedCriteria;
+    private Map<String, From> fromMap;
 
-    public JpaFromProvider(DetachedCriteria detachedCriteria) {
-        this.detachedCriteria = detachedCriteria;
+    private JpaFromProvider(Map<String, From> fromMap) {
+        this.fromMap = new HashMap<>(fromMap);
     }
 
-    public Map<String, From> getFromsByName(JpaCriteriaQuery<?> cq, From root) 
{
-        var detachedAssociationCriteriaList = getDetachedAssociationCriteria();
+
+    public JpaFromProvider(DetachedCriteria detachedCriteria, 
JpaCriteriaQuery<?> cq, From root) {
+        fromMap = getFromsByName(detachedCriteria, cq, root);
+    }
+
+    private Map<String, From> getFromsByName(DetachedCriteria 
detachedCriteria, JpaCriteriaQuery<?> cq, From root) {
+        var detachedAssociationCriteriaList = ((List<Query.Criterion>) 
detachedCriteria.getCriteria())
+                .stream()
+                .map(new DetachedAssociationFunction())
+                .flatMap(List::stream)
+                .toList();
 
         var aliasMap = createAliasMap(detachedAssociationCriteriaList);
         //The join column is column for joining from the root entity
         var detachedFroms = createDetachedFroms(cq, 
detachedAssociationCriteriaList);
-        Map<String, From> fromsByName = 
Stream.concat(aliasMap.keySet().stream(), collectJoinColumns().stream())
+        Map<String, From> fromsByName = 
Stream.concat(aliasMap.keySet().stream(), ((Map<String, FetchType>) 
detachedCriteria.getFetchStrategies())
+                        .entrySet()
+                        .stream()
+                        .filter(entry -> 
entry.getValue().equals(FetchType.EAGER))
+                        .map(Map.Entry::getKey)
+                        .toList().stream())
                 .distinct()
                 .map(joinColumn -> {
-                    var table = detachedFroms.computeIfAbsent(joinColumn, s -> 
root).join(joinColumn, getJoinType(joinColumn));
+                    var table = detachedFroms.computeIfAbsent(joinColumn, s -> 
root).join(joinColumn, ((Map<String, JoinType>) detachedCriteria.getJoinTypes())
+                            .entrySet()
+                            .stream()
+                            .filter(entry -> entry.getKey().equals(joinColumn))
+                            .map(Map.Entry::getValue)
+                            .findFirst()
+                            .orElse(JoinType.INNER));
                     // Attempt to find specific criteria configuration for 
this association path
                     var column = Optional.ofNullable(aliasMap.get(joinColumn))
                             .map(detachedAssociationCriteria -> 
Objects.requireNonNullElse(detachedAssociationCriteria.getAlias(), joinColumn))
@@ -45,16 +68,6 @@ public class JpaFromProvider {
         return fromsByName;
     }
 
-    private JoinType getJoinType(String joinColumn) {
-        return getDetachedCriteriaJoinTypes()
-        .entrySet()
-        .stream()
-        .filter(entry -> entry.getKey().equals(joinColumn))
-        .map(Map.Entry::getValue)
-        .findFirst()
-        .orElse(JoinType.INNER);
-    }
-
     private Map<String, From> createDetachedFroms(JpaCriteriaQuery<?> cq, 
List<DetachedAssociationCriteria> detachedAssociationCriteriaList) {
         return detachedAssociationCriteriaList.stream()
                 .collect(Collectors.toMap(
@@ -69,37 +82,29 @@ public class JpaFromProvider {
                 .collect(Collectors.toMap(Map.Entry::getKey, 
Map.Entry::getValue));
     }
 
-    @SuppressWarnings("unchecked")
-    private List<Query.Criterion> getDetachedCriteria() {
-        return detachedCriteria.getCriteria();
-    }
-
-    private List<DetachedAssociationCriteria> getDetachedAssociationCriteria() 
{
-        return getDetachedCriteria()
-                .stream()
-                .map(new DetachedAssociationFunction())
-                .flatMap(List::stream)
-                .toList();
+    public Path getFullyQualifiedPath(String propertyName) {
+        if (Objects.isNull(propertyName) || propertyName.trim().isEmpty()) {
+            throw new IllegalArgumentException("propertyName cannot be null");
+        }
+        String[] parsed = propertyName.split("\\.");
+        if (parsed.length == 1) {
+            if (fromMap.containsKey(propertyName)) {
+                return fromMap.get(propertyName);
+            } else {
+               return fromMap.get("root").get(propertyName);
+            }
+        }
+        String tableName =  parsed[0];
+        String columnName =  parsed[1];
+        return fromMap.get(tableName).get(columnName);
     }
 
-    private List<String> collectJoinColumns() {
-        return getDetachedCriteriaFetchStrategies()
-                .entrySet()
-                .stream()
-                .filter(entry -> entry.getValue().equals(FetchType.EAGER))
-                .map(Map.Entry::getKey)
-                .toList();
+    public Object clone() {
+        return new JpaFromProvider(fromMap);
     }
 
-    @SuppressWarnings("unchecked")
-    private Map<String, JoinType> getDetachedCriteriaJoinTypes() {
-        return detachedCriteria.getJoinTypes();
-    }
 
-    @SuppressWarnings("unchecked")
-    private Map<String,FetchType> getDetachedCriteriaFetchStrategies() {
-        return detachedCriteria.getFetchStrategies();
+    public void put(String tableName, From child) {
+        fromMap.put(tableName, child);
     }
-
-
 }
diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
index e36f390431..e9a4caa540 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.java
@@ -5,14 +5,12 @@ import jakarta.persistence.criteria.CriteriaQuery;
 import jakarta.persistence.criteria.From;
 import jakarta.persistence.criteria.Join;
 import jakarta.persistence.criteria.JoinType;
-import jakarta.persistence.criteria.Path;
 import jakarta.persistence.criteria.Predicate;
 import jakarta.persistence.criteria.Root;
 import jakarta.persistence.criteria.Subquery;
 import org.grails.datastore.gorm.query.criteria.DetachedAssociationCriteria;
 import org.grails.datastore.mapping.query.Query;
 import org.hibernate.query.criteria.HibernateCriteriaBuilder;
-import org.hibernate.query.criteria.JpaExpression;
 import org.hibernate.query.criteria.JpaInPredicate;
 import org.hibernate.query.sqm.tree.predicate.SqmInListPredicate;
 import org.slf4j.Logger;
@@ -29,8 +27,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
-import static 
org.grails.orm.hibernate.query.AbstractHibernateQuery.getFullyQualifiedPath;
-
 
 @Slf4j
 public class PredicateGenerator {
@@ -39,7 +35,7 @@ public class PredicateGenerator {
     public static Predicate[] getPredicates(HibernateCriteriaBuilder cb,
                                             CriteriaQuery criteriaQuery,
                                             From root_,
-                                            List<Query.Criterion> 
criteriaList, Map<String, From> tablesByName) {
+                                            List<Query.Criterion> 
criteriaList, JpaFromProvider tablesByName) {
 
 
         List<Predicate> list = criteriaList.stream().
@@ -56,7 +52,7 @@ public class PredicateGenerator {
                     } else if (criterion instanceof 
DetachedAssociationCriteria<?> c) {
                             Join child = root_.join(c.getAssociationPath(), 
JoinType.LEFT);
                             List<Query.Criterion> criterionList = 
c.getCriteria();
-                            Map<String, From> childTablesByName = new 
HashMap<>(tablesByName);
+                            JpaFromProvider childTablesByName = 
(JpaFromProvider )tablesByName.clone();
                             childTablesByName.put("root",child);
                             return cb.and(getPredicates(cb, criteriaQuery, 
child, criterionList, childTablesByName));
                     } else if (criterion instanceof Query.Negation) {
@@ -68,87 +64,87 @@ public class PredicateGenerator {
                         }
                         return cb.not(predicates[0]);
                     } else if (criterion instanceof Query.IsNull c) {
-                        return cb.isNull(getFullyQualifiedPath(tablesByName, 
c.getProperty()));
+                        return 
cb.isNull(tablesByName.getFullyQualifiedPath(c.getProperty()));
                     } else if (criterion instanceof Query.IsNotNull c) {
-                        return 
cb.isNotNull(getFullyQualifiedPath(tablesByName, c.getProperty()));
+                        return 
cb.isNotNull(tablesByName.getFullyQualifiedPath(c.getProperty()));
                     } else if (criterion instanceof Query.IsEmpty c) {
-                        return cb.isEmpty(getFullyQualifiedPath(tablesByName, 
c.getProperty()));
+                        return 
cb.isEmpty(tablesByName.getFullyQualifiedPath(c.getProperty()));
                     } else if (criterion instanceof Query.Equals c) {
-                        return cb.equal(getFullyQualifiedPath(tablesByName, 
c.getProperty()), c.getValue());
+                        return 
cb.equal(tablesByName.getFullyQualifiedPath(c.getProperty()), c.getValue());
                     } else if (criterion instanceof Query.NotEquals c) {
-                        return cb.notEqual(getFullyQualifiedPath(tablesByName, 
c.getProperty()), c.getValue());
+                        return 
cb.notEqual(tablesByName.getFullyQualifiedPath(c.getProperty()), c.getValue());
                     } else if (criterion instanceof Query.EqualsProperty c) {
-                        return cb.equal(getFullyQualifiedPath(tablesByName, 
c.getProperty()), root_.get(c.getOtherProperty()));
+                        return 
cb.equal(tablesByName.getFullyQualifiedPath(c.getProperty()), 
root_.get(c.getOtherProperty()));
                     } else if (criterion instanceof Query.NotEqualsProperty c) 
{
-                        return cb.notEqual(getFullyQualifiedPath(tablesByName, 
c.getProperty()), root_.get(c.getOtherProperty()));
+                        return 
cb.notEqual(tablesByName.getFullyQualifiedPath(c.getProperty()), 
root_.get(c.getOtherProperty()));
                     } else if (criterion instanceof 
Query.LessThanEqualsProperty c) {
-                        return cb.le(getFullyQualifiedPath(tablesByName, 
c.getProperty()), root_.get(c.getOtherProperty()));
+                        return 
cb.le(tablesByName.getFullyQualifiedPath(c.getProperty()), 
root_.get(c.getOtherProperty()));
                     } else if (criterion instanceof Query.LessThanProperty c) {
-                        return cb.lt(getFullyQualifiedPath(tablesByName, 
c.getProperty()), root_.get(c.getOtherProperty()));
+                        return 
cb.lt(tablesByName.getFullyQualifiedPath(c.getProperty()), 
root_.get(c.getOtherProperty()));
                     } else if (criterion instanceof 
Query.GreaterThanEqualsProperty c) {
-                        return cb.ge(getFullyQualifiedPath(tablesByName, 
c.getProperty()), root_.get(c.getOtherProperty()));
+                        return 
cb.ge(tablesByName.getFullyQualifiedPath(c.getProperty()), 
root_.get(c.getOtherProperty()));
                     } else if (criterion instanceof Query.GreaterThanProperty 
c) {
-                        return cb.gt(getFullyQualifiedPath(tablesByName, 
c.getProperty()), root_.get(c.getOtherProperty()));
+                        return 
cb.gt(tablesByName.getFullyQualifiedPath(c.getProperty()), 
root_.get(c.getOtherProperty()));
                     } else if (criterion instanceof Query.IdEquals c) {
                         return cb.equal(root_.get("id"), c.getValue());
                     } else if (criterion instanceof Query.GreaterThan c) {
-                        return cb.gt(getFullyQualifiedPath(tablesByName, 
c.getProperty()), (Number) c.getValue());
+                        return 
cb.gt(tablesByName.getFullyQualifiedPath(c.getProperty()), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.GreaterThanEquals c) 
{
-                        return cb.ge(getFullyQualifiedPath(tablesByName, 
c.getProperty()), (Number) c.getValue());
+                        return 
cb.ge(tablesByName.getFullyQualifiedPath(c.getProperty()), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.LessThan c) {
-                        return cb.lt(getFullyQualifiedPath(tablesByName, 
c.getProperty()), (Number) c.getValue());
+                        return 
cb.lt(tablesByName.getFullyQualifiedPath(c.getProperty()), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.LessThanEquals c) {
-                        return cb.le(getFullyQualifiedPath(tablesByName, 
c.getProperty()), (Number) c.getValue());
+                        return 
cb.le(tablesByName.getFullyQualifiedPath(c.getProperty()), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.SizeEquals c) {
-                        return 
cb.equal(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), 
c.getValue());
+                        return 
cb.equal(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), 
c.getValue());
                     } else if (criterion instanceof Query.SizeNotEquals c) {
-                        return 
cb.notEqual(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), 
c.getValue());
+                        return 
cb.notEqual(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), 
c.getValue());
                     } else if (criterion instanceof Query.SizeGreaterThan c) {
-                        return 
cb.gt(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.gt(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof 
Query.SizeGreaterThanEquals c) {
-                        return 
cb.ge(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.ge(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.SizeLessThan c) {
-                        return 
cb.lt(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.lt(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.SizeLessThanEquals 
c) {
-                        return 
cb.le(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.le(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.Between c) {
                         if (c.getFrom() instanceof String && c.getTo() 
instanceof String) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (String) 
c.getFrom(), (String) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (String) 
c.getFrom(), (String) c.getTo());
                         } else if (c.getFrom() instanceof Short && c.getTo() 
instanceof Short) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (Short) 
c.getFrom(), (Short) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (Short) 
c.getFrom(), (Short) c.getTo());
                         } else if (c.getFrom() instanceof Integer && c.getTo() 
instanceof Integer) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (Integer) 
c.getFrom(), (Integer) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (Integer) 
c.getFrom(), (Integer) c.getTo());
                         } else if (c.getFrom() instanceof Long && c.getTo() 
instanceof Long) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (Long) 
c.getFrom(), (Long) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (Long) 
c.getFrom(), (Long) c.getTo());
                         } else if (c.getFrom() instanceof Date && c.getTo() 
instanceof Date) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (Date) 
c.getFrom(), (Date) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (Date) 
c.getFrom(), (Date) c.getTo());
                         } else if (c.getFrom() instanceof Instant && c.getTo() 
instanceof Instant) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (Instant) 
c.getFrom(), (Instant) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (Instant) 
c.getFrom(), (Instant) c.getTo());
                         } else if (c.getFrom() instanceof LocalDate && 
c.getTo() instanceof LocalDate) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), (LocalDate) 
c.getFrom(), (LocalDate) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (LocalDate) 
c.getFrom(), (LocalDate) c.getTo());
                         } else if (c.getFrom() instanceof LocalDateTime && 
c.getTo() instanceof LocalDateTime) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), 
(LocalDateTime) c.getFrom(), (LocalDateTime) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (LocalDateTime) 
c.getFrom(), (LocalDateTime) c.getTo());
                         } else if (c.getFrom() instanceof OffsetDateTime && 
c.getTo() instanceof OffsetDateTime) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), 
(OffsetDateTime) c.getFrom(), (OffsetDateTime) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), 
(OffsetDateTime) c.getFrom(), (OffsetDateTime) c.getTo());
                         } else if (c.getFrom() instanceof ZonedDateTime && 
c.getTo() instanceof ZonedDateTime) {
-                            return 
cb.between(getFullyQualifiedPath(tablesByName, c.getProperty()), 
(ZonedDateTime) c.getFrom(), (ZonedDateTime) c.getTo());
+                            return 
cb.between(tablesByName.getFullyQualifiedPath(c.getProperty()), (ZonedDateTime) 
c.getFrom(), (ZonedDateTime) c.getTo());
                         }
                     } else if (criterion instanceof Query.ILike c) {
-                        return cb.ilike(getFullyQualifiedPath(tablesByName, 
c.getProperty()), c.getValue().toString());
+                        return 
cb.ilike(tablesByName.getFullyQualifiedPath(c.getProperty()), 
c.getValue().toString());
                     } else if (criterion instanceof Query.RLike c) {
-                        return cb.like(getFullyQualifiedPath(tablesByName, 
c.getProperty()), c.getPattern(), '\\');
+                        return 
cb.like(tablesByName.getFullyQualifiedPath(c.getProperty()), c.getPattern(), 
'\\');
                     } else if (criterion instanceof Query.Like c) {
-                        return cb.like(getFullyQualifiedPath(tablesByName, 
c.getProperty()), c.getValue().toString());
+                        return 
cb.like(tablesByName.getFullyQualifiedPath(c.getProperty()), 
c.getValue().toString());
                     } else if (criterion instanceof Query.SizeEquals c) {
-                        return 
cb.equal(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), 
c.getValue());
+                        return 
cb.equal(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), 
c.getValue());
                     } else if (criterion instanceof Query.SizeGreaterThan c) {
-                        return 
cb.gt(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.gt(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof 
Query.SizeGreaterThanEquals c) {
-                        return 
cb.ge(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.ge(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.SizeLessThan c) {
-                        return 
cb.lt(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.lt(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (criterion instanceof Query.SizeLessThanEquals 
c) {
-                        return 
cb.le(cb.size(getFullyQualifiedPath(tablesByName, c.getProperty())), (Number) 
c.getValue());
+                        return 
cb.le(cb.size(tablesByName.getFullyQualifiedPath(c.getProperty())), (Number) 
c.getValue());
                     } else if (
                             criterion instanceof Query.In c
                             && Objects.nonNull(c.getSubquery())
@@ -161,11 +157,10 @@ public class PredicateGenerator {
                         Subquery subquery = 
criteriaQuery.subquery(getJavaTypeOfInClause((SqmInListPredicate) in));
                         Root from = 
subquery.from(c.getSubquery().getPersistentEntity().getJavaClass());
                         List subCriteria = c.getSubquery().getCriteria();
-                        Map<String,From> newMap = new HashMap<>();
-                        newMap.putAll(tablesByName);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
                         newMap.put("root", from);
                         Predicate[] predicates = getPredicates(cb, 
criteriaQuery, from, subCriteria, newMap);
-                        
subquery.select(getFullyQualifiedPath(newMap,projection.getPropertyName())).distinct(distinct).where(cb.and(predicates));
+                        
subquery.select(newMap.getFullyQualifiedPath(projection.getPropertyName())).distinct(distinct).where(cb.and(predicates));
                         return in.value(subquery);
                     } else if (
                             criterion instanceof Query.NotIn c
@@ -179,11 +174,10 @@ public class PredicateGenerator {
                         Subquery subquery = 
criteriaQuery.subquery(getJavaTypeOfInClause((SqmInListPredicate) in));
                         Root from = 
subquery.from(c.getSubquery().getPersistentEntity().getJavaClass());
                         List subCriteria = c.getSubquery().getCriteria();
-                        Map<String,From> newMap = new HashMap<>();
-                        newMap.putAll(tablesByName);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
                         newMap.put("root", from);
                         Predicate[] predicates = getPredicates(cb, 
criteriaQuery, from, subCriteria, newMap);
-                        
subquery.select(getFullyQualifiedPath(newMap,projection.getPropertyName())).distinct(distinct).where(cb.and(predicates));
+                        
subquery.select(newMap.getFullyQualifiedPath(projection.getPropertyName())).distinct(distinct).where(cb.and(predicates));
                         return cb.not(in.value(subquery));
                     } else if (criterion instanceof Query.In c
                             && Objects.nonNull(c.getSubquery())
@@ -194,8 +188,7 @@ public class PredicateGenerator {
                         Subquery subquery = 
criteriaQuery.subquery(getJavaTypeOfInClause((SqmInListPredicate) in));
                         Root from = 
subquery.from(c.getSubquery().getPersistentEntity().getJavaClass());
                         List subCriteria = c.getSubquery().getCriteria();
-                        Map<String,From> newMap = new HashMap<>();
-                        newMap.putAll(tablesByName);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
                         newMap.put("root", from);
                         Predicate[] predicates = getPredicates(cb, 
criteriaQuery, from, subCriteria, newMap);
                         subquery.select(from).where(cb.and(predicates));
@@ -209,31 +202,30 @@ public class PredicateGenerator {
                         Subquery subquery = 
criteriaQuery.subquery(getJavaTypeOfInClause((SqmInListPredicate) in));
                         Root from = 
subquery.from(c.getSubquery().getPersistentEntity().getJavaClass());
                         List subCriteria = c.getSubquery().getCriteria();
-                        Map<String,From> newMap = new HashMap<>();
-                        newMap.putAll(tablesByName);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
                         newMap.put("root", from);
                         Predicate[] predicates = getPredicates(cb, 
criteriaQuery, from, subCriteria, newMap);
                         subquery.select(from).where(cb.and(predicates));
                         return cb.not(in.value(subquery));
                     } else if (criterion instanceof Query.In c && 
!c.getValues().isEmpty()
                     ) {
-                        return cb.in(getFullyQualifiedPath(tablesByName, 
c.getProperty()), c.getValues());
+                        return 
cb.in(tablesByName.getFullyQualifiedPath(c.getProperty()), c.getValues());
                     } else if (criterion instanceof Query.NotIn c
                     ) {
-                        return 
cb.not(cb.in(getFullyQualifiedPath(tablesByName, c.getProperty()), 
c.getValue()));
+                        return 
cb.not(cb.in(tablesByName.getFullyQualifiedPath(c.getProperty()), 
c.getValue()));
                     } else if (criterion instanceof Query.Exists c) {
                         Subquery subquery = 
criteriaQuery.subquery(Object.class);
                         Root subRoot = 
subquery.from(c.getSubquery().getPersistentEntity().getJavaClass());
-                        HashMap<String, From> subMap = new 
HashMap<>(tablesByName);
-                        subMap.put("root", subRoot);
-                        Predicate[] predicates = getPredicates(cb, 
criteriaQuery, subRoot, c.getSubquery().getCriteria(), subMap);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
+                        newMap.put("root", subRoot);
+                        Predicate[] predicates = getPredicates(cb, 
criteriaQuery, subRoot, c.getSubquery().getCriteria(), newMap);
                         
subquery.select(cb.literal(1)).where(cb.and(predicates));
                         return cb.exists(subquery);
                     } else if (criterion instanceof Query.NotExists c) {
                         Subquery subquery = 
criteriaQuery.subquery(Object.class);
                         Root subRoot = 
subquery.from(c.getSubquery().getPersistentEntity().getJavaClass());
-                        HashMap<String, From> subMap = new 
HashMap<>(tablesByName);
-                        subMap.put("root", subRoot);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
+                        newMap.put("root", subRoot);
                         Predicate[] predicates = getPredicates(cb, 
criteriaQuery, subRoot, c.getSubquery().getCriteria(), tablesByName);
                         
subquery.select(cb.literal(1)).where(cb.and(predicates));
                         return cb.not(cb.exists(subquery));
@@ -241,37 +233,36 @@ public class PredicateGenerator {
                         Subquery subquery = 
criteriaQuery.subquery(Number.class);
                         Root from = 
subquery.from(c.getValue().getPersistentEntity().getJavaClass());
                         List subCriteria = c.getValue().getCriteria();
-                        Map<String,From> newMap = new HashMap<>();
-                        newMap.putAll(tablesByName);
+                        JpaFromProvider newMap = (JpaFromProvider) 
tablesByName.clone();
                         newMap.put("root", from);
                         Predicate[] predicates = getPredicates(cb, 
criteriaQuery, from, subCriteria, newMap);
                         if (c instanceof Query.GreaterThanEqualsAll sc) {
                             
subquery.select(cb.max(from.get(c.getProperty()))).where(cb.and(predicates));
-                            return 
cb.greaterThanOrEqualTo(getFullyQualifiedPath(tablesByName, sc.getProperty()), 
subquery);
+                            return 
cb.greaterThanOrEqualTo(tablesByName.getFullyQualifiedPath(sc.getProperty()), 
subquery);
                         } else if (c instanceof Query.GreaterThanAll sc) {
                             
subquery.select(cb.max(from.get(c.getProperty()))).where(cb.and(predicates));
-                            return 
cb.greaterThan(getFullyQualifiedPath(tablesByName, sc.getProperty()), subquery);
+                            return 
cb.greaterThan(tablesByName.getFullyQualifiedPath(sc.getProperty()), subquery);
                         } else if (c instanceof Query.LessThanEqualsAll sc) {
                             
subquery.select(cb.min(from.get(c.getProperty()))).where(cb.and(predicates));
-                            return 
cb.lessThanOrEqualTo(getFullyQualifiedPath(tablesByName, sc.getProperty()), 
subquery);
+                            return 
cb.lessThanOrEqualTo(tablesByName.getFullyQualifiedPath(sc.getProperty()), 
subquery);
                         } else if (c instanceof Query.LessThanAll sc) {
                             
subquery.select(cb.min(from.get(c.getProperty()))).where(cb.and(predicates));
-                            return 
cb.lessThan(getFullyQualifiedPath(tablesByName, sc.getProperty()), subquery);
+                            return 
cb.lessThan(tablesByName.getFullyQualifiedPath(sc.getProperty()), subquery);
                         } else if (c instanceof Query.EqualsAll sc) {
                             
subquery.select(from.get(c.getProperty())).where(cb.and(predicates));
-                            return 
cb.equal(getFullyQualifiedPath(tablesByName, sc.getProperty()), subquery);
+                            return 
cb.equal(tablesByName.getFullyQualifiedPath(sc.getProperty()), subquery);
                         } else if (c instanceof Query.GreaterThanEqualsSome 
sc) {
                             
subquery.select(cb.max(from.get(c.getProperty()))).where(cb.or(predicates));
-                            return 
cb.greaterThanOrEqualTo(getFullyQualifiedPath(tablesByName, sc.getProperty()), 
subquery);
+                            return 
cb.greaterThanOrEqualTo(tablesByName.getFullyQualifiedPath(sc.getProperty()), 
subquery);
                         } else if (c instanceof Query.GreaterThanSome sc) {
                             
subquery.select(cb.max(from.get(c.getProperty()))).where(cb.or(predicates));
-                            return 
cb.greaterThan(getFullyQualifiedPath(tablesByName, sc.getProperty()), subquery);
+                            return 
cb.greaterThan(tablesByName.getFullyQualifiedPath(sc.getProperty()), subquery);
                         } else if (c instanceof Query.LessThanEqualsSome sc) {
                             
subquery.select(cb.min(from.get(c.getProperty()))).where(cb.or(predicates));
-                            return 
cb.lessThanOrEqualTo(getFullyQualifiedPath(tablesByName, sc.getProperty()), 
subquery);
+                            return 
cb.lessThanOrEqualTo(tablesByName.getFullyQualifiedPath(sc.getProperty()), 
subquery);
                         } else if (c instanceof Query.LessThanSome sc) {
                             
subquery.select(cb.min(from.get(c.getProperty()))).where(cb.or(predicates));
-                            return 
cb.lessThan(getFullyQualifiedPath(tablesByName, sc.getProperty()), subquery);
+                            return 
cb.lessThan(tablesByName.getFullyQualifiedPath(sc.getProperty()), subquery);
                         } else if (criterion instanceof Query.NotIn sc
                                 && Objects.nonNull(sc.getSubquery())
                                 && !sc.getSubquery().getProjections().isEmpty()
@@ -280,7 +271,7 @@ public class PredicateGenerator {
                             Query.PropertyProjection projection = 
(Query.PropertyProjection) sc.getSubquery().getProjections().get(0);
                             boolean distinct = projection instanceof 
Query.DistinctPropertyProjection;
                             
subquery.select(from.get(projection.getPropertyName())).distinct(distinct).where(cb.and(predicates));
-                            return cb.in(getFullyQualifiedPath(tablesByName, 
sc.getProperty())).value(subquery);
+                            return 
cb.in(tablesByName.getFullyQualifiedPath(sc.getProperty())).value(subquery);
                         } else if (criterion instanceof Query.NotIn sc
                                 && Objects.nonNull(sc.getSubquery())
                                 && !sc.getSubquery().getProjections().isEmpty()


Reply via email to