jamesfredley commented on code in PR #16696:
URL: https://github.com/apache/grails-core/pull/16696#discussion_r4341352815
##########
.github/workflows/gradle.yml:
##########
@@ -19,6 +19,8 @@ on:
branches:
- '[0-9]+.[0-9]+.x'
pull_request:
+ # CHANGEME FOR ACCEPTANCE: PR triggers disabled on this stacked branch;
revert before merge
+ branches: ['CHANGEME-FOR-ACCEPTANCE']
Review Comment:
`branches` here filters the pull request base. `CHANGEME-FOR-ACCEPTANCE`
matches no release branch, so this workflow does not run for this pull request
or for a pull request targeting `9.0.x` / `8.0.x` / `7.0.x`.
The same placeholder is in the other 12 workflow files in this delta:
benchmark, build-health, codeanalysis, codeql, codestyle, coverage, end-to-end,
groovy-snapshot-canary, rat, sitemesh2, validate-actions, and
vulnerability-scan.
Restore those trigger blocks to the base versions before merge.
##########
grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/PredicateGenerator.groovy:
##########
@@ -111,20 +178,113 @@ class PredicateGenerator {
}
+ /**
+ * Extension point for ordering a criteria query by something other than a
property. Register a handler for a
+ * {@link Query.Order} subclass to have it converted to a JPA {@link
jakarta.persistence.criteria.Order}, in
+ * the place the order has among the query's orders. The order reaches the
query through
+ * {@code order(Query.Order)} of the criteria builder or of a detached
criteria.
+ *
+ * <pre>
+ * class ByRandom extends Query.Order {
+ * ByRandom() { super('random') }
+ * }
+ * PredicateGenerator.registerOrderHandler(ByRandom) { query, root,
cb, order, context ->
+ * cb.asc(cb.function('random', Double))
+ * }
+ * </pre>
+ *
+ * @since 10.0
+ */
+ @FunctionalInterface
+ static interface OrderHandler {
+
+ /**
+ * @param criteriaQuery the query, whose result type tells a query for
the entity from a projection
+ * @param root the root of the query
+ * @param criteriaBuilder the criteria builder
+ * @param order the order to convert
+ * @param context the context of the query: its root, its joins and
its aliases
+ * @return the JPA order, or {@code null} to leave this order out of
the query
+ */
+ jakarta.persistence.criteria.Order handle(
+ CriteriaQuery<?> criteriaQuery,
+ From<?, ?> root,
+ HibernateCriteriaBuilder criteriaBuilder,
+ Query.Order order,
+ JpaQueryContext context
+ )
+
+ }
+
+ /**
+ * SPI for contributing an {@link OrderHandler} via {@link ServiceLoader}.
Register an implementation in
+ * {@code
META-INF/services/org.grails.orm.hibernate.query.PredicateGenerator$OrderHandlerProvider};
it is
+ * discovered on first query execution, like a {@link
CriterionHandlerProvider}.
+ *
+ * @since 10.0
+ */
+ static interface OrderHandlerProvider {
+
+ Class<? extends Query.Order> orderType()
+
+ OrderHandler orderHandler()
+
+ }
+
public static final Map<Class<? extends Query.Criterion>,
CriterionHandler> CUSTOM_HANDLERS =
new ConcurrentHashMap<>()
+ public static final Map<Class<? extends Query.Order>, OrderHandler>
CUSTOM_ORDER_HANDLERS =
+ new ConcurrentHashMap<>()
+
private static final AtomicBoolean SERVICE_LOADERS_INITIALIZED = new
AtomicBoolean(false)
private static void loadServiceProviders() {
if (SERVICE_LOADERS_INITIALIZED.compareAndSet(false, true)) {
Review Comment:
`compareAndSet(false, true)` runs before `ServiceLoader` finishes. A second
request sees the flag already true, skips `loadServiceProviders()`, and
`orderHandler()` returns null. `JpaCriteriaQueryCreator` then treats the custom
order as a property order. A synthetic property such as the documented `random`
sorts wrong or throws.
The early flag is older than this delta. This change is what puts
order-handler discovery on that path.
Make concurrent callers wait until discovery finishes. Keep programmatic
registration ahead of a discovered handler. Please add a test where one thread
is blocked inside order-provider loading and a second query still receives the
handler.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]