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 4cd2661dedb5c83b8d14e88e50d89572570a50a9
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Sat Aug 9 23:39:42 2025 -0500

    consolidate classes
---
 .../grails/orm/HibernateCriteriaBuilder.java       | 1391 +++++++++++++++++++-
 .../AbstractHibernateGormStaticApi.groovy          |    2 +
 .../grails/orm/hibernate/query/HibernateQuery.java |    5 +
 3 files changed, 1362 insertions(+), 36 deletions(-)

diff --git 
a/grails-data-hibernate6/core/src/main/groovy/grails/orm/HibernateCriteriaBuilder.java
 
b/grails-data-hibernate6/core/src/main/groovy/grails/orm/HibernateCriteriaBuilder.java
index d8262622d5..ac8a7da24c 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/grails/orm/HibernateCriteriaBuilder.java
+++ 
b/grails-data-hibernate6/core/src/main/groovy/grails/orm/HibernateCriteriaBuilder.java
@@ -16,33 +16,64 @@
 package grails.orm;
 
 import grails.gorm.DetachedCriteria;
+import grails.gorm.MultiTenant;
+import groovy.lang.Closure;
+import groovy.lang.DelegatesTo;
+import groovy.lang.GroovyObjectSupport;
 import groovy.lang.GroovySystem;
+import groovy.lang.MetaClass;
+import groovy.lang.MetaMethod;
+import groovy.lang.MissingMethodException;
+import groovy.util.logging.Slf4j;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.JoinType;
+import jakarta.persistence.criteria.Root;
+import jakarta.persistence.criteria.Subquery;
 import jakarta.persistence.metamodel.Attribute;
+import jakarta.persistence.metamodel.EntityType;
+import jakarta.persistence.metamodel.Metamodel;
 import jakarta.persistence.metamodel.PluralAttribute;
+import org.grails.datastore.mapping.multitenancy.MultiTenancySettings;
+import org.grails.datastore.mapping.query.Query;
+import org.grails.datastore.mapping.query.api.BuildableCriteria;
+import org.grails.datastore.mapping.query.api.Criteria;
+import org.grails.datastore.mapping.query.api.QueryableCriteria;
+import org.grails.datastore.mapping.reflect.NameUtils;
 import org.grails.orm.hibernate.AbstractHibernateDatastore;
+import org.grails.orm.hibernate.AbstractHibernateSession;
 import org.grails.orm.hibernate.GrailsHibernateTemplate;
 import org.grails.orm.hibernate.HibernateDatastore;
-import org.grails.orm.hibernate.query.AbstractHibernateCriteriaBuilder;
+import org.grails.orm.hibernate.query.HibernateQuery;
+import org.grails.orm.hibernate.query.HibernateQueryConstants;
+import org.hibernate.FetchMode;
+import org.hibernate.Session;
 import org.hibernate.SessionFactory;
+import org.hibernate.transform.ResultTransformer;
 import org.hibernate.type.BasicTypeReference;
 import org.hibernate.type.StandardBasicTypes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.core.convert.ConversionService;
+import org.grails.datastore.mapping.query.api.ProjectionList;
 
-import org.springframework.orm.hibernate5.SessionHolder;
-import 
org.springframework.transaction.support.TransactionSynchronizationManager;
-import org.grails.datastore.mapping.query.api.QueryableCriteria;
-
-
+import java.beans.PropertyDescriptor;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.sql.Blob;
 import java.sql.Clob;
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Currency;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.TimeZone;
 import java.util.UUID;
 
@@ -73,7 +104,8 @@ import java.util.UUID;
  *
  * @author Graeme Rocher
  */
-public class HibernateCriteriaBuilder extends AbstractHibernateCriteriaBuilder 
{
+@Slf4j
+public class HibernateCriteriaBuilder extends GroovyObjectSupport implements 
BuildableCriteria, ProjectionList {
     /*
      * Define constants which may be used inside of criteria queries
      * to refer to standard Hibernate Type instances.
@@ -116,74 +148,1361 @@ public class HibernateCriteriaBuilder extends 
AbstractHibernateCriteriaBuilder {
     public static final BasicTypeReference<String> MATERIALIZED_CLOB = 
StandardBasicTypes.MATERIALIZED_CLOB;
     public static final BasicTypeReference<Serializable> SERIALIZABLE = 
StandardBasicTypes.SERIALIZABLE;
 
+    public static final String AND = "and"; // builder
+    public static final String IS_NULL = "isNull"; // builder
+    public static final String IS_NOT_NULL = "isNotNull"; // builder
+    public static final String NOT = "not";// builder
+    public static final String OR = "or"; // builder
+    public static final String ID_EQUALS = "idEq"; // builder
+    public static final String IS_EMPTY = "isEmpty"; //builder
+    public static final String IS_NOT_EMPTY = "isNotEmpty"; //builder
+    public static final String RLIKE = "rlike";//method
+    public static final String BETWEEN = "between";//method
+    public static final String EQUALS = "eq";//method
+    public static final String EQUALS_PROPERTY = "eqProperty";//method
+    public static final String GREATER_THAN = "gt";//method
+    public static final String GREATER_THAN_PROPERTY = "gtProperty";//method
+    public static final String GREATER_THAN_OR_EQUAL = "ge";//method
+    public static final String GREATER_THAN_OR_EQUAL_PROPERTY = 
"geProperty";//method
+    public static final String ILIKE = "ilike";//method
+    public static final String IN = "in";//method
+    public static final String LESS_THAN = "lt"; //method
+    public static final String LESS_THAN_PROPERTY = "ltProperty";//method
+    public static final String LESS_THAN_OR_EQUAL = "le";//method
+    public static final String LESS_THAN_OR_EQUAL_PROPERTY = 
"leProperty";//method
+    public static final String LIKE = "like";//method
+    public static final String NOT_EQUAL = "ne";//method
+    public static final String NOT_EQUAL_PROPERTY = "neProperty";//method
+    public static final String SIZE_EQUALS = "sizeEq"; //method
+    public static final String ORDER_DESCENDING = "desc";
+    public static final String ORDER_ASCENDING = "asc";
+    protected static final String ROOT_DO_CALL = "doCall";
+    protected static final String ROOT_CALL = "call";
+    protected static final String LIST_CALL = "list";
+    protected static final String LIST_DISTINCT_CALL = "listDistinct";
+    protected static final String COUNT_CALL = "count";
+    protected static final String GET_CALL = "get";
+    protected static final String SCROLL_CALL = "scroll";
+    protected static final String SET_RESULT_TRANSFORMER_CALL = 
"setResultTransformer";
+    protected static final String PROJECTIONS = "projections";
+    private static final Logger log = 
LoggerFactory.getLogger(HibernateCriteriaBuilder.class);
+
+
+    protected SessionFactory sessionFactory;
+    protected Session hibernateSession;
+    protected Class<?> targetClass;
+    protected Query.Junction junction = new Query.Conjunction();
+    protected CriteriaQuery criteriaQuery;
+    protected MetaClass criteriaMetaClass;
+    protected boolean uniqueResult = false;
+    protected List<LogicalExpression> logicalExpressionStack = new 
ArrayList<LogicalExpression>();
+    protected List<String> associationStack = new ArrayList<String>();
+    protected boolean participate;
+    protected boolean scroll;
+    protected boolean count;
+    protected Query.ProjectionList projectionList = new Query.ProjectionList();
+    protected List<String> aliasStack = new ArrayList<String>();
+    protected Map<String, String> aliasMap = new HashMap<String, String>();
+    protected static final String ALIAS = "_alias";
+    protected ResultTransformer resultTransformer;
+    protected int aliasCount;
+    protected boolean paginationEnabledList = false;
+    protected ConversionService conversionService;
+    protected int defaultFlushMode;
+    protected AbstractHibernateDatastore datastore;
+    protected org.hibernate.query.criteria.HibernateCriteriaBuilder cb;
+    protected Root root;
+    protected Subquery subquery;
+    protected HibernateQuery hibernateQuery;
+    private boolean shouldLock;
+    private boolean shouldCache;
+    private boolean readOnly;
+    private boolean distinct = false;
+
     @SuppressWarnings("rawtypes")
     public HibernateCriteriaBuilder(Class targetClass, SessionFactory 
sessionFactory, AbstractHibernateDatastore datastore) {
-        super(targetClass, sessionFactory, datastore);
+        this.targetClass = targetClass;
+        setDatastore(datastore);
+        this.sessionFactory = sessionFactory;
+        this.cb = sessionFactory.getCriteriaBuilder();
+        AbstractHibernateSession session =(AbstractHibernateSession) 
datastore.connect();
+        hibernateQuery = new HibernateQuery(session, 
datastore.getMappingContext().getPersistentEntity(targetClass.getTypeName()));
         setDefaultFlushMode(GrailsHibernateTemplate.FLUSH_AUTO);
     }
 
-    @Override
+    public void setDatastore(AbstractHibernateDatastore datastore) {
+        this.datastore = datastore;
+        if(MultiTenant.class.isAssignableFrom(targetClass) && 
datastore.getMultiTenancyMode() == 
MultiTenancySettings.MultiTenancyMode.DISCRIMINATOR ) {
+            datastore.enableMultiTenancyFilter();
+        }
+    }
+
+    public void setConversionService(ConversionService conversionService) {
+        this.conversionService = conversionService;
+    }
+
+    /**
+     * A projection that selects a property name
+     * @param propertyName The name of the property
+     */
+    public ProjectionList property(String propertyName) {
+        hibernateQuery.projections().property(propertyName);
+        return this;
+    }
+
+    /**
+     * A projection that selects a distince property name
+     * @param propertyName The property name
+     */
+    public ProjectionList distinct(String propertyName) {
+        hibernateQuery.projections().distinct(propertyName);
+        return this;
+    }
+
+
+    /**
+     * Adds a projection that allows the criteria to return the property 
average value
+     *
+     * @param propertyName The name of the property
+     */
+    public ProjectionList avg(String propertyName) {
+        hibernateQuery.projections().avg(propertyName);
+        return this;
+    }
+
+    /**
+     * Use a join query
+     *
+     * @param associationPath The path of the association
+     */
+    public BuildableCriteria join(String associationPath) {
+        join(associationPath,JoinType.INNER);
+        return this;
+    }
+
+    public BuildableCriteria join(String property, JoinType joinType) {
+        hibernateQuery.join(property,joinType);
+        return this;
+    }
+
+
+    /**
+     * Whether a pessimistic lock should be obtained.
+     *
+     * @param shouldLock True if it should
+     */
+    public void lock(boolean shouldLock) {
+        this.shouldLock = shouldLock;
+    }
+
+    /**
+     * Use a select query
+     *
+     * @param associationPath The path of the association
+     */
+    public BuildableCriteria select(String associationPath) {
+        hibernateQuery.select(associationPath);
+        return this;
+    }
+
+    /**
+     * Whether to use the query cache
+     * @param shouldCache True if the query should be cached
+     */
+    public BuildableCriteria cache(boolean shouldCache) {
+        this.shouldCache = shouldCache;
+        return this;
+    }
+
+
+    public BuildableCriteria maxResults(int max) {
+        hibernateQuery.maxResults(max);
+        return this;
+    }
+
+    /**
+     * Whether to check for changes on the objects loaded
+     * @param readOnly True to disable dirty checking
+     */
+    public BuildableCriteria readOnly(boolean readOnly) {
+        this.readOnly = readOnly;
+        return this;
+    }
+
+    /**
+     * Calculates the property name including any alias paths
+     *
+     * @param propertyName The property name
+     * @return The calculated property name
+     */
+    protected String calculatePropertyName(String propertyName) {
+        return propertyName;
+    }
+
+    private String getLastAlias() {
+        if (aliasStack.size() > 0) {
+            return aliasStack.get(aliasStack.size() - 1).toString();
+        }
+        return null;
+    }
+
+    public Class<?> getTargetClass() {
+        return targetClass;
+    }
+
     protected DetachedCriteria convertToHibernateCriteria(QueryableCriteria<?> 
queryableCriteria) {
         return null;
     }
 
+    /**
+     * Adds a projection that allows the criteria to return the property count
+     *
+     * @param propertyName The name of the property
+     */
+    public void count(String propertyName) {
+        count(propertyName, null);
+    }
 
-    protected Class getClassForAssociationType(Attribute<?, ?> type) {
-        if (type instanceof PluralAttribute) {
-            return ((PluralAttribute)type).getElementType().getJavaType();
+    /**
+     * Adds a projection that allows the criteria to return the property count
+     *
+     * @param propertyName The name of the property
+     * @param alias The alias to use
+     */
+    public void count(String propertyName, String alias) {
+        
hibernateQuery.projections().countDistinct(getFullyQualifiedColumn(propertyName,
 alias));
+    }
+
+    private static String getFullyQualifiedColumn(String propertyName, String 
alias) {
+        return (Objects.nonNull(alias) ? alias + "." : "") + propertyName;
+    }
+
+    public ProjectionList id() {
+        hibernateQuery.projections().id();
+        return this;
+    }
+
+    public ProjectionList count() {
+        return rowCount();
+    }
+
+    /**
+     * Adds a projection that allows the criteria to return the distinct 
property count
+     *
+     * @param propertyName The name of the property
+     */
+    public ProjectionList countDistinct(String propertyName) {
+        return countDistinct(propertyName, null);
+    }
+
+    /**
+     * Adds a projection that allows the criteria to return the distinct 
property count
+     *
+     * @param propertyName The name of the property
+     */
+    public ProjectionList groupProperty(String propertyName) {
+        return groupProperty(propertyName, null);
+    }
+
+    public ProjectionList distinct() {
+        hibernateQuery.projections().distinct();
+        return this;
+    }
+
+    /**
+     * Adds a projection that allows the criteria to return the distinct 
property count
+     *
+     * @param propertyName The name of the property
+     * @param alias The alias to use
+     */
+    public ProjectionList countDistinct(String propertyName, String alias) {
+        
hibernateQuery.projections().countDistinct(getFullyQualifiedColumn(propertyName,alias));
+        return this;
+    }
+
+
+    /**
+     * Adds a projection that allows the criteria's result to be grouped by a 
property
+     *
+     * @param propertyName The name of the property
+     * @param alias The alias to use
+     */
+    public ProjectionList groupProperty(String propertyName, String alias) {
+        
hibernateQuery.projections().groupProperty(getFullyQualifiedColumn(propertyName,alias));
+        return this;
+    }
+
+    /**
+     * Adds a projection that allows the criteria to retrieve a  maximum 
property value
+     *
+     * @param propertyName The name of the property
+     */
+    public ProjectionList max(String propertyName) {
+        return max(propertyName, null);
+    }
+
+    /**
+     * Adds a projection that allows the criteria to retrieve a  maximum 
property value
+     *
+     * @param propertyName The name of the property
+     * @param alias The alias to use
+     */
+    public ProjectionList max(String propertyName, String alias) {
+        
hibernateQuery.projections().max(getFullyQualifiedColumn(propertyName,alias));
+        return this;
+    }
+
+    /**
+     * Adds a projection that allows the criteria to retrieve a  minimum 
property value
+     *
+     * @param propertyName The name of the property
+     */
+    public ProjectionList min(String propertyName) {
+        return min(propertyName, null);
+    }
+
+    /**
+     * Adds a projection that allows the criteria to retrieve a  minimum 
property value
+     *
+     * @param alias The alias to use
+     */
+    public ProjectionList min(String propertyName, String alias) {
+        
hibernateQuery.projections().min(getFullyQualifiedColumn(propertyName,alias));
+        return this;
+    }
+
+    /**
+     * Adds a projection that allows the criteria to return the row count
+     *
+     */
+    public ProjectionList rowCount() {
+        return count();
+    }
+
+
+    /**
+     * Adds a projection that allows the criteria to retrieve the sum of the 
results of a property
+     *
+     * @param propertyName The name of the property
+     */
+    public ProjectionList sum(String propertyName) {
+        return sum(propertyName, null);
+    }
+
+    /**
+     * Adds a projection that allows the criteria to retrieve the sum of the 
results of a property
+     *
+     * @param propertyName The name of the property
+     * @param alias The alias to use
+     */
+    public ProjectionList sum(String propertyName, String alias) {
+        
hibernateQuery.projections().sum(getFullyQualifiedColumn(propertyName,alias));
+        return this;
+    }
+
+    /**
+     * Sets the fetch mode of an associated path
+     *
+     * @param associationPath The name of the associated path
+     * @param fetchMode The fetch mode to set
+     */
+    public void fetchMode(String associationPath, FetchMode fetchMode) {
+        if (fetchMode.equals(FetchMode.SELECT)){
+            hibernateQuery.getDetachedCriteria().select(associationPath);
+        } else {
+            hibernateQuery.getDetachedCriteria().join(associationPath);
         }
-        return type.getJavaType();
+
+    }
+
+    /**
+     * Sets the resultTransformer.
+     * @param transformer The result transformer to use.
+     */
+    public void resultTransformer(ResultTransformer transformer) {
+        hibernateQuery.setResultTransformer(transformer);
+    }
+
+
+    /**
+     * Creates a Criterion that compares to class properties for equality
+     * @param propertyName The first property name
+     * @param otherPropertyName The second property name
+     * @return A Criterion instance
+     */
+    public Criteria eqProperty(String propertyName, String otherPropertyName) {
+        hibernateQuery.eqProperty(propertyName,otherPropertyName);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that compares to class properties for !equality
+     * @param propertyName The first property name
+     * @param otherPropertyName The second property name
+     * @return A Criterion instance
+     */
+    public Criteria neProperty(String propertyName, String otherPropertyName) {
+        hibernateQuery.neProperty(propertyName,otherPropertyName);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that tests if the first property is greater than 
the second property
+     * @param propertyName The first property name
+     * @param otherPropertyName The second property name
+     * @return A Criterion instance
+     */
+    public Criteria gtProperty(String propertyName, String otherPropertyName) {
+        hibernateQuery.gtProperty(propertyName,otherPropertyName);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that tests if the first property is greater than or 
equal to the second property
+     * @param propertyName The first property name
+     * @param otherPropertyName The second property name
+     * @return A Criterion instance
+     */
+    public Criteria geProperty(String propertyName, String otherPropertyName) {
+        hibernateQuery.geProperty(propertyName,otherPropertyName);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that tests if the first property is less than the 
second property
+     * @param propertyName The first property name
+     * @param otherPropertyName The second property name
+     * @return A Criterion instance
+     */
+    public Criteria ltProperty(String propertyName, String otherPropertyName) {
+        hibernateQuery.ltProperty(propertyName,otherPropertyName);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that tests if the first property is less than or 
equal to the second property
+     * @param propertyName The first property name
+     * @param otherPropertyName The second property name
+     * @return A Criterion instance
+     */
+    public Criteria leProperty(String propertyName, String otherPropertyName) {
+        hibernateQuery.leProperty(propertyName,otherPropertyName);
+        return this;
+    }
+
+    @Override
+    public Criteria allEq(Map<String, Object> propertyValues) {
+        hibernateQuery.allEq(propertyValues);
+        return this;
+    }
+
+
+    /**
+     * Creates a subquery criterion that ensures the given property is equal 
to all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public Criteria eqAll(String propertyName, Closure<?> propertyValue) {
+        return eqAll(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+
+    /**
+     * Creates a subquery criterion that ensures the given property is greater 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public Criteria gtAll(String propertyName, Closure<?> propertyValue) {
+        return gtAll(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is less 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public Criteria ltAll(String propertyName, Closure<?> propertyValue) {
+        return ltAll(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is greater 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public Criteria geAll(String propertyName, Closure<?> propertyValue) {
+        return geAll(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is less 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public Criteria leAll(String propertyName, Closure<?> propertyValue) {
+        return leAll(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is equal 
to all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria eqAll(String propertyName, @SuppressWarnings("rawtypes") 
QueryableCriteria propertyValue) {
+        hibernateQuery.eqAll(propertyName,propertyValue);
+        return this;
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is greater 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria gtAll(String propertyName, @SuppressWarnings("rawtypes") 
QueryableCriteria propertyValue) {
+        hibernateQuery.gtAll(propertyName,propertyValue);
+        return this;
+    }
+
+    @Override
+    public Criteria gtSome(String propertyName, QueryableCriteria 
propertyValue) {
+        return this;
+    }
+
+    @Override
+    public Criteria gtSome(String propertyName, Closure<?> propertyValue) {
+        return gtSome(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    @Override
+    public Criteria geSome(String propertyName, QueryableCriteria 
propertyValue) {
+        hibernateQuery.geSome(propertyName,propertyValue);
+        return this;
+    }
+
+    @Override
+    public Criteria geSome(String propertyName, Closure<?> propertyValue) {
+        return geSome(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    @Override
+    public Criteria ltSome(String propertyName, QueryableCriteria 
propertyValue) {
+        hibernateQuery.ltSome(propertyName,propertyValue);
+        return this;
+    }
+
+    @Override
+    public Criteria ltSome(String propertyName, Closure<?> propertyValue) {
+        return ltSome(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    @Override
+    public Criteria leSome(String propertyName, QueryableCriteria 
propertyValue) {
+        hibernateQuery.leSome(propertyName,propertyValue);
+        return this;
+    }
+
+    @Override
+    public Criteria leSome(String propertyName, Closure<?> propertyValue) {
+        return leSome(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(propertyValue));
+    }
+
+    @Override
+    public Criteria in(String propertyName, QueryableCriteria<?> subquery) {
+        return inList(propertyName, subquery);
+    }
+
+    @Override
+    public Criteria inList(String propertyName, QueryableCriteria<?> subquery) 
{
+        hibernateQuery.in(propertyName,subquery);
+        return this;
+    }
+
+    @Override
+    public Criteria in(String propertyName, Closure<?> subquery) {
+        return inList(propertyName, new 
DetachedCriteria(targetClass).build(subquery));
+    }
+
+    @Override
+    public Criteria inList(String propertyName, Closure<?> subquery) {
+        return inList(propertyName, new 
DetachedCriteria(targetClass).build(subquery));
+    }
+
+    @Override
+    public Criteria notIn(String propertyName, QueryableCriteria<?> subquery) {
+        hibernateQuery.notIn(propertyName,subquery);
+        return this;
     }
 
     @Override
+    public Criteria notIn(String propertyName, Closure<?> subquery) {
+        return notIn(propertyName, new 
grails.gorm.DetachedCriteria(targetClass).build(subquery));
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is less 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria ltAll(String propertyName, @SuppressWarnings("rawtypes") 
QueryableCriteria propertyValue) {
+        hibernateQuery.ltAll(propertyName,propertyValue);
+        return this;
+
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is greater 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria geAll(String propertyName, @SuppressWarnings("rawtypes") 
QueryableCriteria propertyValue) {
+        hibernateQuery.geAll(propertyName,propertyValue);
+        return this;
+
+    }
+
+    /**
+     * Creates a subquery criterion that ensures the given property is less 
than all the given returned values
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria leAll(String propertyName, @SuppressWarnings("rawtypes") 
QueryableCriteria propertyValue) {
+        hibernateQuery.leAll(propertyName,propertyValue);
+        return this;
+    }
+
+    /**
+     * Creates a "greater than" Criterion based on the specified property name 
and value
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria gt(String propertyName, Object propertyValue) {
+        hibernateQuery.gt(propertyName,propertyValue);
+        return this;
+    }
+
+    public Criteria lte(String s, Object o) {
+        return le(s,o);
+    }
+
+    /**
+     * Creates a "greater than or equal to" Criterion based on the specified 
property name and value
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria ge(String propertyName, Object propertyValue) {
+        hibernateQuery.ge(propertyName,propertyValue);
+        return this;
+    }
+
+    /**
+     * Creates a "less than" Criterion based on the specified property name 
and value
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria lt(String propertyName, Object propertyValue) {
+        hibernateQuery.lt(propertyName,propertyValue);
+        return this;
+    }
+
+    /**
+     * Creates a "less than or equal to" Criterion based on the specified 
property name and value
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     * @return A Criterion instance
+     */
+    public Criteria le(String propertyName, Object propertyValue) {
+        hibernateQuery.le(propertyName,propertyValue);
+        return this;
+    }
+
+    public Criteria idEquals(Object o) {
+        return idEq(o);
+    }
+
+    @Override
+    public Criteria exists(QueryableCriteria<?> subquery) {
+        hibernateQuery.exists(subquery);
+        return this;
+    }
+
+    @Override
+    public Criteria notExists(QueryableCriteria<?> subquery) {
+        hibernateQuery.notExits(subquery);
+        return this;
+    }
+
+    public Criteria isEmpty(String property) {
+        hibernateQuery.isEmpty(property);
+        return this;
+    }
+
+    public Criteria isNotEmpty(String property) {
+        hibernateQuery.isNotEmpty(property);
+        return this;
+    }
+
+    public Criteria isNull(String property) {
+        hibernateQuery.isNull(property);
+        return this;
+    }
+
+    public Criteria isNotNull(String property) {
+        hibernateQuery.isNotNull(property);
+        return this;
+    }
+
+    @Override
+    public Criteria and(Closure callable) {
+        hibernateQuery.and(callable);
+        return this;
+    }
+
+    @Override
+    public Criteria or(Closure callable) {
+        hibernateQuery.or(callable);
+        return this;
+    }
+
+    @Override
+    public Criteria not(Closure callable) {
+        hibernateQuery.not(callable);
+        return this;
+    }
+
+    /**
+     * Creates an "equals" Criterion based on the specified property name and 
value. Case-sensitive.
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     *
+     * @return A Criterion instance
+     */
+    public Criteria eq(String propertyName, Object propertyValue) {
+        return eq(propertyName, propertyValue, Collections.emptyMap());
+    }
+
+    public Criteria idEq(Object o) {
+        return eq("id", o);
+    }
+
+    /**
+     * Groovy moves the map to the first parameter if using the idiomatic 
form, e.g.
+     * <code>eq 'firstName', 'Fred', ignoreCase: true</code>.
+     * @param params optional map with customization parameters; currently 
only 'ignoreCase' is supported.
+     * @param propertyName
+     * @param propertyValue
+     * @return A Criterion instance
+     */
+    @SuppressWarnings("rawtypes")
+    public Criteria eq(Map params, String propertyName, Object propertyValue) {
+        return eq(propertyName, propertyValue, params);
+    }
+
+    /**
+     * Creates an "equals" Criterion based on the specified property name and 
value.
+     * Supports case-insensitive search if the <code>params</code> map 
contains <code>true</code>
+     * under the 'ignoreCase' key.
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     * @param params optional map with customization parameters; currently 
only 'ignoreCase' is supported.
+     *
+     * @return A Criterion instance
+     */
+    @SuppressWarnings("rawtypes")
+    public Criteria eq(String propertyName, Object propertyValue, Map params) {
+        if (params.get("ignoreCase") == Boolean.TRUE) {
+            hibernateQuery.like(propertyName,  "%" + propertyValue.toString() 
+ "%");
+        } else {
+            hibernateQuery.eq(propertyName,propertyValue);
+        }
+        return this;
+    }
+
+
+
+    /**
+     * Creates a Criterion with from the specified property name and "like" 
expression
+     * @param propertyName The property name
+     * @param propertyValue The like value
+     *
+     * @return A Criterion instance
+     */
+    public Criteria like(String propertyName, Object propertyValue) {
+        hibernateQuery.like(propertyName,propertyValue.toString());
+        return this;
+    }
+
+
+
+    /**
+     * Creates a Criterion with from the specified property name and "ilike" 
(a case sensitive version of "like") expression
+     * @param propertyName The property name
+     * @param propertyValue The ilike value
+     *
+     * @return A Criterion instance
+     */
+    public Criteria ilike(String propertyName, Object propertyValue) {
+        hibernateQuery.ilike(propertyName,propertyValue.toString());
+        return this;
+    }
+
+    /**
+     * Applys a "in" contrain on the specified property
+     * @param propertyName The property name
+     * @param values A collection of values
+     *
+     * @return A Criterion instance
+     */
+    @SuppressWarnings("rawtypes")
+    public Criteria in(String propertyName, Collection values) {
+        hibernateQuery.in(propertyName,values.stream().toList());
+        return this;
+    }
+
+    /**
+     * Delegates to in as in is a Groovy keyword
+     */
+    @SuppressWarnings("rawtypes")
+    public Criteria inList(String propertyName, Collection values) {
+        return in(propertyName, values);
+    }
+
+    /**
+     * Delegates to in as in is a Groovy keyword
+     */
+    public Criteria inList(String propertyName, Object[] values) {
+        return in(propertyName, values);
+    }
+
+    /**
+     * Applys a "in" contrain on the specified property
+     * @param propertyName The property name
+     * @param values A collection of values
+     *
+     * @return A Criterion instance
+     */
+    public Criteria in(String propertyName, Object[] values) {
+        hibernateQuery.in(propertyName, List.of(values));
+        return this;
+    }
+
+    /**
+     * Orders by the specified property name (defaults to ascending)
+     *
+     * @param propertyName The property name to order by
+     * @return A Order instance
+     */
+    public Criteria order(String propertyName) {
+        order(new Query.Order(propertyName));
+        return this;
+    }
+
+    @Override
+    public Criteria order(Query.Order o) {
+        hibernateQuery.order(o);
+        return this;
+    }
+
+    public Criteria firstResult(int offset) {
+        hibernateQuery.firstResult(offset);
+        return this;
+    }
+
+    /**
+     * Orders by the specified property name and direction
+     *
+     * @param propertyName The property name to order by
+     * @param directionString Either "asc" for ascending or "desc" for 
descending
+     *
+     * @return A Order instance
+     */
+    public Criteria order(String propertyName, String directionString) {
+        Query.Order.Direction direction = 
Query.Order.Direction.DESC.name().equalsIgnoreCase(directionString) ? 
Query.Order.Direction.DESC : Query.Order.Direction.ASC;
+        hibernateQuery.order(new Query.Order(propertyName, direction));
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that contrains a collection property by size
+     *
+     * @param propertyName The property name
+     * @param size The size to constrain by
+     *
+     * @return A Criterion instance
+     */
+    public Criteria sizeEq(String propertyName, int size) {
+        hibernateQuery.sizeEq(propertyName,size);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that contrains a collection property to be greater 
than the given size
+     *
+     * @param propertyName The property name
+     * @param size The size to constrain by
+     *
+     * @return A Criterion instance
+     */
+    public Criteria sizeGt(String propertyName, int size) {
+        hibernateQuery.sizeGt(propertyName,size);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that contrains a collection property to be greater 
than or equal to the given size
+     *
+     * @param propertyName The property name
+     * @param size The size to constrain by
+     *
+     * @return A Criterion instance
+     */
+    public Criteria sizeGe(String propertyName, int size) {
+        hibernateQuery.sizeGe(propertyName,size);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that contrains a collection property to be less 
than or equal to the given size
+     *
+     * @param propertyName The property name
+     * @param size The size to constrain by
+     *
+     * @return A Criterion instance
+     */
+    public Criteria sizeLe(String propertyName, int size) {
+        hibernateQuery.sizeLe(propertyName,size);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that contrains a collection property to be less 
than to the given size
+     *
+     * @param propertyName The property name
+     * @param size The size to constrain by
+     *
+     * @return A Criterion instance
+     */
+    public Criteria sizeLt(String propertyName, int size) {
+        hibernateQuery.sizeLt(propertyName,size);
+        return this;
+    }
+
+    /**
+     * Creates a Criterion with from the specified property name and "rlike" 
(a regular expression version of "like") expression
+     *
+     * @param propertyName  The property name
+     * @param propertyValue The ilike value
+     * @return A Criterion instance
+     */
+    public org.grails.datastore.mapping.query.api.Criteria rlike(String 
propertyName, Object propertyValue) {
+        hibernateQuery.rlike(propertyName,propertyValue.toString());
+        return this;
+    }
+
+    /**
+     * Creates a Criterion that contrains a collection property to be not 
equal to the given size
+     *
+     * @param propertyName The property name
+     * @param size The size to constrain by
+     *
+     * @return A Criterion instance
+     */
+    public Criteria sizeNe(String propertyName, int size) {
+        hibernateQuery.sizeNe(propertyName,size);
+        return this;
+    }
+
+    /**
+     * Creates a "not equal" Criterion based on the specified property name 
and value
+     * @param propertyName The property name
+     * @param propertyValue The property value
+     * @return The criterion object
+     */
+    public Criteria ne(String propertyName, Object propertyValue) {
+        hibernateQuery.ne(propertyName,propertyValue);
+        return this;
+    }
+
+
+    /**
+     * Creates a "between" Criterion based on the property name and specified 
lo and hi values
+     * @param propertyName The property name
+     * @param lo The low value
+     * @param hi The high value
+     * @return A Criterion instance
+     */
+    public Criteria between(String propertyName, Object lo, Object hi) {
+        hibernateQuery.between(propertyName,lo,hi);
+        return this;
+    }
+
+    public Criteria gte(String s, Object o) {
+        return ge(s, o);
+    }
+
+
+    @Override
+    public Object list(@DelegatesTo(Criteria.class) Closure c) {
+        return invokeMethod(LIST_CALL, new Object[]{c});
+    }
+
+    @Override
+    public Object list(Map params, @DelegatesTo(Criteria.class) Closure c) {
+        return invokeMethod(LIST_CALL, new Object[]{params, c});
+    }
+    
+    @Override
+    public Object listDistinct(@DelegatesTo(Criteria.class) Closure c) {
+        return invokeMethod(LIST_DISTINCT_CALL, new Object[]{c});
+    }
+
+    @Override
+    public Object get(@DelegatesTo(Criteria.class) Closure c) {
+        return invokeMethod(GET_CALL, new Object[]{c});
+    }
+    
+    @Override
+    public Object scroll(@DelegatesTo(Criteria.class) Closure c) {
+        return invokeMethod(SCROLL_CALL, new Object[]{c});
+    }
+
+    public JoinType convertFromInt(Integer from) {
+        return switch (from) {
+            case 1 -> JoinType.LEFT;
+            case 2 -> JoinType.RIGHT;
+            default -> JoinType.INNER;
+        };
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Object invokeMethod(String name, Object obj) {
+        Object[] args = obj.getClass().isArray() ? (Object[])obj : new 
Object[]{obj};
+
+        if (paginationEnabledList && SET_RESULT_TRANSFORMER_CALL.equals(name) 
&& args.length == 1 &&
+                args[0] instanceof ResultTransformer) {
+            hibernateQuery.setResultTransformer((ResultTransformer) args[0]);
+            return null;
+        }
+
+        if (isCriteriaConstructionMethod(name, args)) {
+            if (name.equals(GET_CALL)) {
+                uniqueResult = true;
+            }
+            else if (name.equals(SCROLL_CALL)) {
+                scroll = true;
+            }
+            else if (name.equals(COUNT_CALL)) {
+                count = true;
+            }
+            else if (name.equals(LIST_DISTINCT_CALL)) {
+                distinct = true;
+            }
+
+
+            // Check for pagination params
+            if (name.equals(LIST_CALL) && args.length == 2) {
+                paginationEnabledList = true;
+                invokeClosureNode(args[1]);
+            }
+            else {
+                invokeClosureNode(args[0]);
+            }
+
+            Object result;
+            if (!uniqueResult) {
+                if (distinct) {
+                    hibernateQuery.distinct();
+                    result = hibernateQuery.list();
+                }
+                else if (count) {
+                    hibernateQuery.projections().count();
+                    result = hibernateQuery.singleResult();
+                }
+                else if (paginationEnabledList) {
+                    Map argMap = (Map)args[0];
+                    final String sortField = (String) 
argMap.get(HibernateQueryConstants.ARGUMENT_SORT);
+                    if (sortField != null) {
+                        boolean ignoreCase = true;
+                        Object caseArg = 
argMap.get(HibernateQueryConstants.ARGUMENT_IGNORE_CASE);
+                        if (caseArg instanceof Boolean) {
+                            ignoreCase = (Boolean) caseArg;
+                        }
+                        final String orderParam = (String) 
argMap.get(HibernateQueryConstants.ARGUMENT_ORDER);
+                        final Query.Order.Direction direction = 
Query.Order.Direction.DESC.name().equalsIgnoreCase(orderParam) ? 
Query.Order.Direction.DESC : Query.Order.Direction.ASC;
+                        Query.Order order ;
+                        if (ignoreCase) {
+                            order = new Query.Order(sortField, direction);
+                            order.ignoreCase();
+                        } else {
+                            order = new Query.Order(sortField, direction);
+                        }
+                        hibernateQuery.order(order);
+                    }
+                    result = hibernateQuery.list();
+                }
+                else {
+                    result = hibernateQuery.list();
+                }
+            }
+            else {
+                result = hibernateQuery.singleResult();
+            }
+            if (!participate) {
+                closeSession();
+            }
+            return result;
+        }
+
+        if (criteriaQuery == null) createCriteriaInstance();
+
+        MetaMethod metaMethod = getMetaClass().getMetaMethod(name, args);
+        if (metaMethod != null) {
+            return metaMethod.invoke(this, args);
+        }
+
+        MetaClass metaClass = 
GroovySystem.getMetaClassRegistry().getMetaClass(targetClass);
+        metaMethod = metaClass.getMetaMethod(name, args);
+        if (metaMethod != null) {
+            return metaMethod.invoke(criteriaQuery, args);
+        }
+        metaMethod = metaClass.getMetaMethod(NameUtils.getSetterName(name), 
args);
+        if (metaMethod != null) {
+            return metaMethod.invoke(criteriaQuery, args);
+        }
+
+        if (isAssociationQueryMethod(args) || 
isAssociationQueryWithJoinSpecificationMethod(args)) {
+            final boolean hasMoreThanOneArg = args.length > 1;
+            Closure callable = hasMoreThanOneArg ? (Closure) args[1] : 
(Closure) args[0];
+            JoinType joinType = hasMoreThanOneArg ? 
convertFromInt((Integer)args[0]) : convertFromInt(0);
+
+            if (name.equals(AND)) {
+                hibernateQuery.and(callable);
+                return name;
+            }
+
+            if (name.equals(OR) ) {
+                hibernateQuery.or(callable);
+                return name;
+            }
+
+            if ( name.equals(NOT)) {
+                hibernateQuery.not(callable);
+                return name;
+            }
+
+
+            if (name.equals(PROJECTIONS) && args.length == 1 && (args[0] 
instanceof Closure)) {
+                invokeClosureNode(callable);
+                return name;
+            }
+
+            final PropertyDescriptor pd = 
BeanUtils.getPropertyDescriptor(targetClass, name);
+            if (pd != null && pd.getReadMethod() != null) {
+                final Metamodel metamodel = sessionFactory.getMetamodel();
+                final EntityType<?> entityType = metamodel.entity(targetClass);
+                final Attribute<?, ?> attribute = 
entityType.getAttribute(name);
+
+                if (attribute.isAssociation()) {
+                    Class oldTargetClass = targetClass;
+                    targetClass = getClassForAssociationType(attribute);
+                    if (targetClass.equals(oldTargetClass) && 
!hasMoreThanOneArg) {
+                        joinType = JoinType.LEFT; // default to left join if 
joining on the same table
+                    }
+
+                    hibernateQuery.join(name,joinType);
+                    hibernateQuery.in(name, new 
DetachedCriteria(targetClass).build(callable));
+                    targetClass = oldTargetClass;
+
+                    return name;
+                }
+            }
+        }
+        else if (args.length == 1 && args[0] != null) {
+            Object value = args[0];
+            if (name.equals(ID_EQUALS)) {
+                return eq("id", value);
+            }
+            if (name.equals(IS_NULL) ||
+                    name.equals(IS_NOT_NULL) ||
+                    name.equals(IS_EMPTY) ||
+                    name.equals(IS_NOT_EMPTY)) {
+                if (!(value instanceof String)) {
+                    throwRuntimeException(new IllegalArgumentException("call 
to [" + name + "] with value [" +
+                            value + "] requires a String value."));
+                }
+                String propertyName = calculatePropertyName((String)value);
+                if (name.equals(IS_NULL)) {
+                    hibernateQuery.isNull(propertyName);
+                }
+                else if (name.equals(IS_NOT_NULL)) {
+                    hibernateQuery.isNotNull(propertyName);
+                }
+                else if (name.equals(IS_EMPTY)) {
+                    hibernateQuery.isEmpty(propertyName);
+                }
+                else {
+                    hibernateQuery.isNotEmpty(propertyName);
+                }
+            }
+        }
+        throw new MissingMethodException(name, getClass(), args);
+    }
+
     protected List createPagedResultList(Map args) {
         GrailsHibernateTemplate ght = new 
GrailsHibernateTemplate(sessionFactory, (HibernateDatastore) datastore, 
getDefaultFlushMode());
         return null;
     }
 
+    private boolean isAssociationQueryMethod(Object[] args) {
+        return args.length == 1 && args[0] instanceof Closure;
+    }
+
+    private boolean isAssociationQueryWithJoinSpecificationMethod(Object[] 
args) {
+        return args.length == 2 && (args[0] instanceof Number) && (args[1] 
instanceof Closure);
+    }
 
 
-    @Override
-    protected void createCriteriaInstance() {
-//        {
-//            if 
(TransactionSynchronizationManager.hasResource(sessionFactory)) {
-//                participate = true;
-//                hibernateSession = 
((SessionHolder)TransactionSynchronizationManager.getResource(sessionFactory)).getSession();
-//            }
-//            else {
-//                hibernateSession = sessionFactory.openSession();
-//            }
-//            criteriaQuery = 
hibernateSession.getCriteriaBuilder().createQuery(targetClass);
-//            root = criteriaQuery.from(targetClass);
-//            cacheCriteriaMapping();
-//            criteriaMetaClass = 
GroovySystem.getMetaClassRegistry().getMetaClass(criteriaQuery.getClass());
-//        }
+    private String getAssociationPath() {
+        StringBuilder fullPath = new StringBuilder();
+        for (Object anAssociationStack : associationStack) {
+            String propertyName = (String) anAssociationStack;
+            if (fullPath.length() > 0) fullPath.append(".");
+            fullPath.append(propertyName);
+        }
+        return fullPath.toString();
     }
 
+    private boolean isCriteriaConstructionMethod(String name, Object[] args) {
+        return (name.equals(LIST_CALL) && args.length == 2 && args[0] 
instanceof Map && args[1] instanceof Closure) ||
+                (name.equals(ROOT_CALL) ||
+                        name.equals(ROOT_DO_CALL) ||
+                        name.equals(LIST_CALL) ||
+                        name.equals(LIST_DISTINCT_CALL) ||
+                        name.equals(GET_CALL) ||
+                        name.equals(COUNT_CALL) ||
+                        name.equals(SCROLL_CALL) && args.length == 1 && 
args[0] instanceof Closure);
+    }
+
+    protected void createCriteriaInstance() {
+        // no-op
+    }
 
     protected void cacheCriteriaMapping() {
+        // no-op
+    }
+
+    private void invokeClosureNode(Object args) {
+        Closure<?> callable = (Closure<?>)args;
+        callable.setDelegate(this);
+        callable.setResolveStrategy(Closure.DELEGATE_FIRST);
+        callable.call();
+    }
+
+    /**
+     * adds and returns the given criterion to the currently active criteria 
set.
+     * this might be either the root criteria or a currently open
+     * LogicalExpression.
+     */
+    protected Query.Criterion addToCriteria(Query.Criterion c) {
+        if (false) {
+            // logicalExpressionStack.get(logicalExpressionStack.size() - 
1).args.add(c);
+        }
+        else {
+            junction.add(c);
+        }
+        return c;
+    }
+
+    /**
+     * Returns the criteria instance
+     * @return The criteria instance
+     */
+    public CriteriaQuery getInstance() {
+        return criteriaQuery;
+    }
+
+    /**
+     * Set whether a unique result should be returned
+     * @param uniqueResult True if a unique result should be returned
+     */
+    public void setUniqueResult(boolean uniqueResult) {
+        this.uniqueResult = uniqueResult;
+    }
+
+    protected Class getClassForAssociationType(Attribute<?, ?> type) {
+        if (type instanceof PluralAttribute) {
+            return ((PluralAttribute)type).getElementType().getJavaType();
+        }
+        return type.getJavaType();
+    }
+
+    /**
+     * instances of this class are pushed onto the logicalExpressionStack
+     * to represent all the unfinished "and", "or", and "not" expressions.
+     */
+    protected class LogicalExpression {
+        public final Object name;
 
+        public LogicalExpression(Object name) {
+            this.name = name;
+        }
     }
 
+    /**
+     * Throws a runtime exception where necessary to ensure the session gets 
closed
+     */
+    protected void throwRuntimeException(RuntimeException t) {
+        closeSessionFollowingException();
+        throw t;
+    }
+
+    private void closeSessionFollowingException() {
+        closeSession();
+        criteriaQuery = null;
+    }
 
     /**
      * Closes the session if it is copen
      */
-    @Override
     protected void closeSession() {
         if (hibernateSession != null && hibernateSession.isOpen() && 
!participate) {
             hibernateSession.close();
         }
     }
 
-
-    @Override
-    public Object getProperty(String propertyName) {
-        return super.getProperty(propertyName);
+    public int getDefaultFlushMode() {
+        return defaultFlushMode;
     }
 
-    @Override
-    public void setProperty(String propertyName, Object newValue) {
-        super.setProperty(propertyName, newValue);
+    public void setDefaultFlushMode(int defaultFlushMode) {
+        this.defaultFlushMode = defaultFlushMode;
     }
 }
diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormStaticApi.groovy
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormStaticApi.groovy
index ce913dd186..aa406787bb 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormStaticApi.groovy
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/AbstractHibernateGormStaticApi.groovy
@@ -158,6 +158,8 @@ abstract class AbstractHibernateGormStaticApi<D> extends 
GormStaticApi<D> {
         }
     }
 
+
+
     @Override
     List<D> getAll() {
         (List<D>)hibernateTemplate.execute({ Session session ->
diff --git 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
index df5d405643..52da7237c2 100644
--- 
a/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
+++ 
b/grails-data-hibernate6/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateQuery.java
@@ -68,6 +68,11 @@ public class HibernateQuery extends Query {
 
     protected String alias;
     protected int aliasCount;
+
+    public DetachedCriteria getDetachedCriteria() {
+        return detachedCriteria;
+    }
+
     protected Map<String, CriteriaAndAlias> createdAssociationPaths = new 
HashMap<String, CriteriaAndAlias>();
     protected LinkedList<String> aliasStack = new LinkedList<String>();
     protected LinkedList<PersistentEntity> entityStack = new 
LinkedList<PersistentEntity>();

Reply via email to