From 788bfcb31ec83a883aa6749543865c12661fc8a9 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 13 Sep 2023 18:42:59 +0200 Subject: [PATCH] add CriteriaSelect to fix mistake in design of union/intersect for criteria API --- .../jakarta/persistence/EntityManager.java | 13 +++++ .../persistence/criteria/CriteriaBuilder.java | 12 ++--- .../persistence/criteria/CriteriaQuery.java | 2 +- .../persistence/criteria/CriteriaSelect.java | 30 +++++++++++ .../main/asciidoc/ch03-entity-operations.adoc | 12 +++++ spec/src/main/asciidoc/ch06-criteria-api.adoc | 53 +++++++++++++++++++ 6 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 api/src/main/java/jakarta/persistence/criteria/CriteriaSelect.java diff --git a/api/src/main/java/jakarta/persistence/EntityManager.java b/api/src/main/java/jakarta/persistence/EntityManager.java index bcd38e6e..0c8044f1 100644 --- a/api/src/main/java/jakarta/persistence/EntityManager.java +++ b/api/src/main/java/jakarta/persistence/EntityManager.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.List; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.metamodel.Metamodel; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; @@ -970,6 +971,18 @@ void refresh(Object entity, */ TypedQuery createQuery(CriteriaQuery criteriaQuery); + /** + * Create an instance of {@link TypedQuery} for executing a + * criteria query, which may be a union or intersection of + * top-level queries. + * @param criteriaQuery a criteria query object + * @return the new query instance + * @throws IllegalArgumentException if the criteria query is + * found to be invalid + * @since 3.2 + */ + TypedQuery createQuery(CriteriaSelect criteriaQuery); + /** * Create an instance of {@link Query} for executing a criteria * update query. diff --git a/api/src/main/java/jakarta/persistence/criteria/CriteriaBuilder.java b/api/src/main/java/jakarta/persistence/criteria/CriteriaBuilder.java index 0834c688..2b3ddc5a 100644 --- a/api/src/main/java/jakarta/persistence/criteria/CriteriaBuilder.java +++ b/api/src/main/java/jakarta/persistence/criteria/CriteriaBuilder.java @@ -1807,7 +1807,7 @@ Expression function(String name, Class type, * the results of the given queries * @since 3.2 */ - CriteriaQuery union(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect union(CriteriaSelect left, CriteriaSelect right); /** * Create a query which is the union of the given queries, @@ -1816,7 +1816,7 @@ Expression function(String name, Class type, * the results of the given queries * @since 3.2 */ - CriteriaQuery unionAll(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect unionAll(CriteriaSelect left, CriteriaSelect right); /** * Create a query which is the intersection of the given queries. @@ -1824,7 +1824,7 @@ Expression function(String name, Class type, * the results of the given queries * @since 3.2 */ - CriteriaQuery intersect(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect intersect(CriteriaSelect left, CriteriaSelect right); /** * Create a query which is the intersection of the given queries, @@ -1833,7 +1833,7 @@ Expression function(String name, Class type, * the results of the given queries * @since 3.2 */ - CriteriaQuery intersectAll(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect intersectAll(CriteriaSelect left, CriteriaSelect right); /** * Create a query by (setwise) subtraction of the second query @@ -1843,7 +1843,7 @@ Expression function(String name, Class type, * results of the first query * @since 3.2 */ - CriteriaQuery except(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect except(CriteriaSelect left, CriteriaSelect right); /** * Create a query by (setwise) subtraction of the second query @@ -1853,7 +1853,7 @@ Expression function(String name, Class type, * results of the first query * @since 3.2 */ - CriteriaQuery exceptAll(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect exceptAll(CriteriaSelect left, CriteriaSelect right); } diff --git a/api/src/main/java/jakarta/persistence/criteria/CriteriaQuery.java b/api/src/main/java/jakarta/persistence/criteria/CriteriaQuery.java index 38491bcd..55a48b76 100644 --- a/api/src/main/java/jakarta/persistence/criteria/CriteriaQuery.java +++ b/api/src/main/java/jakarta/persistence/criteria/CriteriaQuery.java @@ -29,7 +29,7 @@ * * @since 2.0 */ -public interface CriteriaQuery extends AbstractQuery { +public interface CriteriaQuery extends AbstractQuery, CriteriaSelect { /** * Specify the item that is to be returned in the query result. diff --git a/api/src/main/java/jakarta/persistence/criteria/CriteriaSelect.java b/api/src/main/java/jakarta/persistence/criteria/CriteriaSelect.java new file mode 100644 index 00000000..c162e275 --- /dev/null +++ b/api/src/main/java/jakarta/persistence/criteria/CriteriaSelect.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +// Contributors: +// Gavin King - 3.2 +// Lukas Jungmann - 3.2 + +package jakarta.persistence.criteria; + +/** + * Abstracts over {@linkplain CriteriaQuery top-level queries} and + * {@linkplain CriteriaBuilder#union unions} and + * {@linkplain CriteriaBuilder#intersect intersections} of top-level + * queries. + * + * @param the type returned by the query + * + * @since 3.2 + */ +public interface CriteriaSelect { +} diff --git a/spec/src/main/asciidoc/ch03-entity-operations.adoc b/spec/src/main/asciidoc/ch03-entity-operations.adoc index a9480ce9..08b44fca 100644 --- a/spec/src/main/asciidoc/ch03-entity-operations.adoc +++ b/spec/src/main/asciidoc/ch03-entity-operations.adoc @@ -862,6 +862,18 @@ public interface EntityManager extends AutoCloseable { */ public TypedQuery createQuery(CriteriaQuery criteriaQuery); + /** + * Create an instance of TypedQuery for executing a + * criteria query, which may be a union or intersection of + * top-level queries. + * @param criteriaQuery a criteria query object + * @return the new query instance + * @throws IllegalArgumentException if the criteria query is + * found to be invalid + * @since 3.2 + */ + TypedQuery createQuery(CriteriaSelect criteriaQuery); + /** * Create an instance of Query for executing a criteria * update query. diff --git a/spec/src/main/asciidoc/ch06-criteria-api.adoc b/spec/src/main/asciidoc/ch06-criteria-api.adoc index fee507d1..c9a29dbf 100644 --- a/spec/src/main/asciidoc/ch06-criteria-api.adoc +++ b/spec/src/main/asciidoc/ch06-criteria-api.adoc @@ -1875,6 +1875,59 @@ Expression... args); */ Root treat(Root root, Class type); + /** + * Create a query which is the union of the given queries. + * @return a new criteria query which returns the union of + * the results of the given queries + * @since 3.2 + */ + CriteriaSelect union(CriteriaSelect left, CriteriaSelect right); + + /** + * Create a query which is the union of the given queries, + * without elimination of duplicate results. + * @return a new criteria query which returns the union of + * the results of the given queries + * @since 3.2 + */ + CriteriaSelect unionAll(CriteriaSelect left, CriteriaSelect right); + + /** + * Create a query which is the intersection of the given queries. + * @return a new criteria query which returns the intersection of + * the results of the given queries + * @since 3.2 + */ + CriteriaSelect intersect(CriteriaSelect left, CriteriaSelect right); + + /** + * Create a query which is the intersection of the given queries, + * without elimination of duplicate results. + * @return a new criteria query which returns the intersection of + * the results of the given queries + * @since 3.2 + */ + CriteriaSelect intersectAll(CriteriaSelect left, CriteriaSelect right); + + /** + * Create a query by (setwise) subtraction of the second query + * from the first query. + * @return a new criteria query which returns the result of + * subtracting the results of the second query from the + * results of the first query + * @since 3.2 + */ + CriteriaSelect except(CriteriaSelect left, CriteriaSelect right); + + /** + * Create a query by (setwise) subtraction of the second query + * from the first query, without elimination of duplicate results. + * @return a new criteria query which returns the result of + * subtracting the results of the second query from the + * results of the first query + * @since 3.2 + */ + CriteriaSelect exceptAll(CriteriaSelect left, CriteriaSelect right); } ----