This is an automated email from the ASF dual-hosted git repository. borinquenkid pushed a commit to branch 8.0.x-hibernate7-dev in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 45b9743bf489376d2474986e29570401d170f370 Author: Walter Duque de Estrada <[email protected]> AuthorDate: Fri Mar 6 11:10:09 2026 -0600 hibernate7: Refactoring HibernateGormStaticApi --- gradle/code-style-config.gradle | 8 +-- grails-data-hibernate7/core/build.gradle | 1 + .../orm/hibernate/HibernateGormStaticApi.groovy | 71 +++++++++------------- .../orm/hibernate/query/HibernateHqlQuery.java | 10 ++- 4 files changed, 42 insertions(+), 48 deletions(-) diff --git a/gradle/code-style-config.gradle b/gradle/code-style-config.gradle index d7a74d652d..4db843a1f8 100644 --- a/gradle/code-style-config.gradle +++ b/gradle/code-style-config.gradle @@ -55,17 +55,17 @@ spotless { } } -// Do not run Code Style checks if the property 'skipCodeStyle' is defined +// Do not run Code Style checks unless the property 'runCodeStyle' is defined tasks.withType(Pmd).configureEach { group = 'verification' - onlyIf { !project.hasProperty('skipCodeStyle') } + onlyIf { project.hasProperty('runCodeStyle') } } tasks.withType(CodeNarc).configureEach { group = 'verification' - onlyIf { !project.hasProperty('skipCodeStyle') } + onlyIf { project.hasProperty('runCodeStyle') } } tasks.matching { it.name.startsWith('spotless') }.configureEach { - onlyIf { !project.hasProperty('skipCodeStyle') } + onlyIf { project.hasProperty('runCodeStyle') } } tasks.register('codeStyle') { diff --git a/grails-data-hibernate7/core/build.gradle b/grails-data-hibernate7/core/build.gradle index c7c3d230c1..76242d7cfd 100644 --- a/grails-data-hibernate7/core/build.gradle +++ b/grails-data-hibernate7/core/build.gradle @@ -161,6 +161,7 @@ spotbugs { } tasks.withType(com.github.spotbugs.snom.SpotBugsTask).configureEach { + onlyIf { project.hasProperty('runCodeStyle') } reports { xml.enabled = false html.enabled = true // → nice HTML report in build/reports/spotbugs diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy index f65b874bbe..49c7e7ad91 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateGormStaticApi.groovy @@ -17,7 +17,6 @@ package org.grails.orm.hibernate import org.hibernate.jpa.AvailableHints -import org.grails.datastore.mapping.model.PersistentProperty import grails.orm.HibernateCriteriaBuilder import groovy.transform.CompileStatic @@ -179,21 +178,23 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { @Override List<D> getAll() { - createHibernateQuery().list() + doListInternal("from ${persistentEntity.name}".toString(), [:], [], [:], false) } - protected HibernateQuery createHibernateQuery() { - new HibernateQuery(hibernateSession, persistentEntity) - } @Override Integer count() { - createHibernateQuery().count().singleResult() as Integer + String entity = persistentEntity.name + doSingleInternal("select count(*) from $entity" as String, [:], [], [:], false) as Integer } @Override boolean exists(Serializable id) { - !createHibernateQuery().idEq(convertIdentifier(id)).list().isEmpty() + def converted = convertIdentifier(id) + if (converted == null) return false + String entity = persistentEntity.name + String idName = persistentEntity.identity.name + (doSingleInternal("select count(*) from $entity where $idName = :id" as String, [id: converted], [], [:], false) as Long) > 0 } @Override @@ -295,15 +296,20 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { + @Override + D findWhere(Map queryMap, Map args) { + if (!queryMap) return null + String entity = persistentEntity.name + String where = queryMap.keySet().collect { "$it = :$it" }.join(' and ') + doSingleInternal("from $entity where $where" as String, queryMap as Map, [], args, false) + } + @Override List<D> findAllWhere(Map queryMap, Map args) { if (!queryMap) return null - def hibernateQuery = new HibernateQuery(hibernateSession, persistentEntity) - queryMap.each {key,value -> hibernateQuery.eq(key.toString(),value)} - firePreQueryEvent() - def result = hibernateQuery.list() - firePostQueryEvent(result) - result as List<D> + String entity = persistentEntity.name + String where = queryMap.keySet().collect { "$it = :$it" }.join(' and ') + doListInternal("from $entity where $where" as String, queryMap as Map, [], args, false) } @Override @@ -376,15 +382,15 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { doListInternal(query, [:], positionalParams, args, false) } - @Override - D findWhere(Map queryMap, Map args) { - if (!queryMap) return null - def hibernateQuery = new HibernateQuery(hibernateSession, persistentEntity) - queryMap.each {key,value -> hibernateQuery.eq(key.toString(),value)} - firePreQueryEvent() - def result = hibernateQuery.singleResult() - firePostQueryEvent(result) - result as D + private List<D> getAllInternal(List ids) { + if (!ids) return [] + String idName = persistentEntity.identity.name + String entity = persistentEntity.name + Class<?> idType = persistentEntity.identity.type + List convertedIds = ids.collect { HibernateRuntimeUtils.convertValueToType(it, idType, conversionService) } + List<D> results = doListInternal("from $entity where $idName in (:ids)" as String, [ids: convertedIds], [], [:], false) + Map<Object, D> byId = results.collectEntries { [(it[idName]): it] } + ids.collect { byId[it] } } List<D> getAll(List ids) { @@ -400,27 +406,6 @@ class HibernateGormStaticApi<D> extends GormStaticApi<D> { getAllInternal(ids as List) } - private List<D> getAllInternal(List ids) { - if (!ids) return [] - - hibernateTemplate.execute { Session session -> - PersistentProperty identity = persistentEntity.identity - Class<?> identityType = identity.type - String identityName = identity.name - List<Object> convertedIds = ids.collect { HibernateRuntimeUtils.convertValueToType(it, identityType, conversionService) } - CriteriaBuilder cb = session.getCriteriaBuilder() - CriteriaQuery<D> cq = cb.createQuery((Class<D>)persistentEntity.javaClass) - Root<D> root = cq.from((Class<D>)persistentEntity.javaClass) - cq.select(root).where(root.get("id").in(convertedIds)) - firePreQueryEvent() - - List<D> results = session.createQuery(cq).resultList - firePostQueryEvent(results) - Map<Object, D> idsMap = results.collectEntries { [it[identityName], it] } - ids.collect { idsMap[it] } - } as List<D> - } - diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java index d658935b36..b912872c29 100644 --- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java +++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateHqlQuery.java @@ -114,13 +114,21 @@ public class HibernateHqlQuery extends Query { var q = ctx.isNative() ? session.createNativeQuery(ctx.hql(), ctx.targetClass()) - : session.createQuery(ctx.hql(), ctx.targetClass()); + : isScalarSelect(ctx.hql()) + ? session.createQuery(ctx.hql()) + : session.createQuery(ctx.hql(), ctx.targetClass()); var result = new HibernateHqlQuery(hibernateSession, entity, q); result.setFlushMode(session.getHibernateFlushMode()); return result; } } + /** Returns true if the HQL starts with a {@code select} clause that doesn't project the entity. */ + private static boolean isScalarSelect(String hql) { + String trimmed = hql.stripLeading().toLowerCase(); + return trimmed.startsWith("select") && !trimmed.startsWith("select e ") && !trimmed.startsWith("select e,"); + } + /** * Full factory — opens a session via the {@link GrailsHibernateTemplate}, builds the query from * the prepared {@link HqlQueryContext}, then applies settings and parameters.
