From ad26e73c44535059b4d3dcdfcdfc8da0dd953224 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 7 Nov 2023 14:49:27 -0600 Subject: [PATCH] HHH-17377 - Migrate to JPA 3.2 https://hibernate.atlassian.net/browse/HHH-17377 JPA 3.2 B02 --- .../stax/ConfigurationEventReader.java | 2 +- .../engine/spi/SessionDelegatorBaseImpl.java | 6 ++ .../engine/spi/SessionImplementor.java | 6 ++ .../engine/spi/SessionLazyDelegator.java | 7 ++ .../graph/internal/AbstractGraph.java | 46 ++++++++++-- .../hibernate/graph/spi/GraphImplementor.java | 17 ++++- .../AbstractSharedSessionContract.java | 3 +- .../org/hibernate/internal/SessionImpl.java | 35 ++++++++++ .../org/hibernate/query/QueryProducer.java | 3 +- .../criteria/HibernateCriteriaBuilder.java | 40 +++++++---- .../query/criteria/JpaCriteriaQuery.java | 2 +- .../query/criteria/JpaCriteriaSelect.java | 23 ++++++ .../hibernate/query/criteria/JpaSubQuery.java | 2 +- .../spi/HibernateCriteriaBuilderDelegate.java | 35 +++++++++- .../query/spi/QueryProducerImplementor.java | 3 +- .../org/hibernate/query/sqm/NodeBuilder.java | 5 +- .../sqm/internal/SqmCriteriaNodeBuilder.java | 70 +++++++++++++++---- .../sqm/tree/select/SqmSelectStatement.java | 9 ++- .../query/sqm/tree/select/SqmSubQuery.java | 6 +- .../org/hibernate/orm/env/JpaVersion.java | 2 +- 20 files changed, 268 insertions(+), 54 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaSelect.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java index 12a746e8f7..65980ade74 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java @@ -20,7 +20,7 @@ public class ConfigurationEventReader extends AbstractEventReader { public ConfigurationEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) { super( ROOT_ELEMENT_NAME, - ConfigXsdSupport.configurationXsd(), + ConfigXsdSupport.getJPA32(), reader, xmlEventFactory ); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index 9ab118e854..2d30ddfd8a 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -72,6 +72,7 @@ import jakarta.persistence.LockOption; import jakarta.persistence.RefreshOption; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.metamodel.Metamodel; import org.checkerframework.checker.nullness.qual.Nullable; @@ -507,6 +508,11 @@ public class SessionDelegatorBaseImpl implements SessionImplementor { return delegate.getEntityGraph( graphName ); } + @Override + public QueryImplementor createQuery(CriteriaSelect selectQuery) { + return delegate.createQuery( selectQuery ); + } + @Override public List> getEntityGraphs(Class entityClass) { return delegate.getEntityGraphs( entityClass ); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java index 8738970c13..05f75f6953 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionImplementor.java @@ -17,11 +17,14 @@ import org.hibernate.event.spi.PersistContext; import org.hibernate.event.spi.RefreshContext; import org.hibernate.graph.spi.RootGraphImplementor; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.query.spi.QueryImplementor; import org.hibernate.resource.jdbc.spi.JdbcSessionOwner; import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; import org.hibernate.type.descriptor.WrapperOptions; +import jakarta.persistence.criteria.CriteriaSelect; + /** * Defines the "internal contract" between {@link Session} and other parts of Hibernate * including implementors of {@link org.hibernate.type.Type}, {@link EntityPersister}, @@ -77,6 +80,9 @@ public interface SessionImplementor extends Session, SharedSessionContractImplem @Override RootGraphImplementor getEntityGraph(String graphName); + @Override + QueryImplementor createQuery(CriteriaSelect selectQuery); + /** * Get the {@link ActionQueue} associated with this session. */ diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java index ef1bfc9318..0d7dc49860 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionLazyDelegator.java @@ -53,8 +53,10 @@ import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.LockOption; import jakarta.persistence.RefreshOption; +import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.metamodel.Metamodel; import org.checkerframework.checker.nullness.qual.Nullable; @@ -591,6 +593,11 @@ public class SessionLazyDelegator implements Session { return this.lazySession.get().createQuery( criteriaQuery ); } + @Override + public TypedQuery createQuery(CriteriaSelect selectQuery) { + return this.lazySession.get().createQuery( selectQuery ); + } + @SuppressWarnings("rawtypes") @Override @Deprecated diff --git a/hibernate-core/src/main/java/org/hibernate/graph/internal/AbstractGraph.java b/hibernate-core/src/main/java/org/hibernate/graph/internal/AbstractGraph.java index 5a398f9909..96a6f983da 100644 --- a/hibernate-core/src/main/java/org/hibernate/graph/internal/AbstractGraph.java +++ b/hibernate-core/src/main/java/org/hibernate/graph/internal/AbstractGraph.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; import org.hibernate.graph.AttributeNode; import org.hibernate.graph.CannotBecomeEntityGraphException; @@ -95,6 +96,42 @@ public abstract class AbstractGraph extends AbstractGraphNode implements G // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AttributeNode handling + + @Override + public AttributeNodeImplementor getAttributeNode(String attributeName) { + if ( attrNodeMap == null ) { + return null; + } + final PersistentAttribute attribute = managedType.findAttributeInSuperTypes( attributeName ); + //noinspection unchecked + return (AttributeNodeImplementor) attrNodeMap.get( attribute ); + } + + @Override + public AttributeNodeImplementor getAttributeNode(Attribute attribute) { + return null; + } + + @Override + public void visitAttributeNodes(Consumer> consumer) { + if ( attrNodeMap == null ) { + return; + } + attrNodeMap.forEach( (persistentAttribute, attributeNodeImplementor) -> { + consumer.accept( attributeNodeImplementor ); + } ); + } + + @Override + public List> getAttributeNodeList() { + if ( attrNodeMap == null ) { + return emptyList(); + } + final List> result = new ArrayList<>(); + visitAttributeNodes( result::add ); + return result; + } + @Override public AttributeNodeImplementor addAttributeNode(AttributeNodeImplementor incomingAttributeNode) { verifyMutability(); @@ -151,8 +188,8 @@ public abstract class AbstractGraph extends AbstractGraphNode implements G } @Override - public void addAttributeNode(String attributeName) throws CannotContainSubGraphException { - findOrCreateAttributeNode( attributeName ); + public AttributeNodeImplementor addAttributeNode(String attributeName) throws CannotContainSubGraphException { + return findOrCreateAttributeNode( attributeName ); } @Override @@ -162,8 +199,9 @@ public abstract class AbstractGraph extends AbstractGraphNode implements G } @Override - public void addAttributeNode(Attribute attribute) { - findOrCreateAttributeNode( (PersistentAttribute) attribute ); + public AttributeNodeImplementor addAttributeNode(Attribute attribute) { + //noinspection unchecked + return (AttributeNodeImplementor) findOrCreateAttributeNode( (PersistentAttribute) attribute ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/graph/spi/GraphImplementor.java b/hibernate-core/src/main/java/org/hibernate/graph/spi/GraphImplementor.java index 20b8306ca1..9d8b0d2a90 100644 --- a/hibernate-core/src/main/java/org/hibernate/graph/spi/GraphImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/graph/spi/GraphImplementor.java @@ -16,6 +16,8 @@ import org.hibernate.graph.Graph; import org.hibernate.metamodel.model.domain.PersistentAttribute; import org.hibernate.query.sqm.SqmPathSource; +import jakarta.persistence.metamodel.Attribute; + /** * Integration version of the {@link Graph} contract * @@ -49,6 +51,16 @@ public interface GraphImplementor extends Graph, GraphNodeImplementor { getAttributeNodeImplementors().forEach( consumer ); } + @Override + default boolean hasAttributeNode(String attributeName) { + return getAttributeNode( attributeName ) != null; + } + + @Override + default boolean hasAttributeNode(Attribute attribute) { + return getAttributeNode( attribute ) != null; + } + AttributeNodeImplementor addAttributeNode(AttributeNodeImplementor makeCopy); List> getAttributeNodeImplementors(); @@ -66,7 +78,10 @@ public interface GraphImplementor extends Graph, GraphNodeImplementor { AttributeNodeImplementor findAttributeNode(PersistentAttribute attribute); @Override - void addAttributeNode(String attributeName) throws CannotContainSubGraphException; + AttributeNodeImplementor addAttributeNode(String attributeName) throws CannotContainSubGraphException; + + @Override + AttributeNodeImplementor addAttributeNode(Attribute attribute); @Override AttributeNodeImplementor addAttributeNode(PersistentAttribute attribute) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index 3a3e80c088..57b0182a25 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -856,6 +856,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return interpretAndCreateSelectionQuery( hqlString, expectedResultType ); } + @Override public SelectionQuery createSelectionQuery(CriteriaQuery criteria) { if ( criteria instanceof CriteriaDefinition ) { @@ -1476,7 +1477,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont } } - private QueryImplementor createCriteriaQuery(SqmStatement criteria, Class resultType) { + protected QueryImplementor createCriteriaQuery(SqmStatement criteria, Class resultType) { final QuerySqmImpl query = new QuerySqmImpl<>( criteria, resultType, this ); applyQuerySettingsAndHints( query ); return query; diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index 0ca7659510..eed440e363 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -124,6 +124,11 @@ import org.hibernate.proxy.LazyInitializer; import org.hibernate.query.Query; import org.hibernate.query.SelectionQuery; import org.hibernate.query.UnknownSqlResultSetMappingException; +import org.hibernate.query.criteria.CriteriaDefinition; +import org.hibernate.query.spi.QueryImplementor; +import org.hibernate.query.sqm.tree.select.SqmQueryGroup; +import org.hibernate.query.sqm.tree.select.SqmQuerySpec; +import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.resource.jdbc.spi.JdbcSessionOwner; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; import org.hibernate.resource.jdbc.spi.StatementInspector; @@ -148,6 +153,7 @@ import jakarta.persistence.LockOption; import jakarta.persistence.PersistenceException; import jakarta.persistence.RefreshOption; import jakarta.persistence.TransactionRequiredException; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.metamodel.Metamodel; import static java.lang.Boolean.parseBoolean; @@ -1719,6 +1725,35 @@ public class SessionImpl return getFactory(); } + @Override + public QueryImplementor createQuery(CriteriaSelect selectQuery) { + checkOpen(); + if ( selectQuery instanceof CriteriaDefinition ) { + return (QueryImplementor) ((CriteriaDefinition) selectQuery).createSelectionQuery(this); + } + else { + try { + final SqmSelectStatement selectStatement = (SqmSelectStatement) selectQuery; + if ( ! ( selectStatement.getQueryPart() instanceof SqmQueryGroup ) ) { + final SqmQuerySpec querySpec = selectStatement.getQuerySpec(); + if ( querySpec.getSelectClause().getSelections().isEmpty() ) { + if ( querySpec.getFromClause().getRoots().size() == 1 ) { + querySpec.getSelectClause().setSelection( querySpec.getFromClause().getRoots().get(0) ); + } + } + } + + return createCriteriaQuery( selectStatement, selectStatement.getResultType() ); + } + catch (RuntimeException e) { + if ( getSessionFactory().getJpaMetamodel().getJpaCompliance().isJpaTransactionComplianceEnabled() ) { + markForRollbackOnly(); + } + throw getExceptionConverter().convert( e ); + } + } + } + @Override public void initializeCollection(PersistentCollection collection, boolean writing) { checkOpenOrWaitingForAutoClose(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java b/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java index a0d4408dcf..fba2d4d8c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java +++ b/hibernate-core/src/main/java/org/hibernate/query/QueryProducer.java @@ -166,8 +166,7 @@ public interface QueryProducer { * * @apiNote Changes in JPA 3.2 required de-typing this to be compilable with their changes */ - @SuppressWarnings("rawtypes") - NativeQuery createNativeQuery(String sqlString, Class resultClass); + NativeQuery createNativeQuery(String sqlString, Class resultClass); /** * Create a {@link NativeQuery} instance for the given native SQL query diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java index 4c99b04edc..8e0999e9c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/HibernateCriteriaBuilder.java @@ -25,12 +25,14 @@ import org.hibernate.query.NullPrecedence; import org.hibernate.query.SortDirection; import org.hibernate.query.sqm.FrameKind; import org.hibernate.query.sqm.TemporalUnit; +import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.AbstractQuery; import jakarta.persistence.criteria.CollectionJoin; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.ListJoin; @@ -176,28 +178,34 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder { JpaCriteriaQuery except(boolean all, CriteriaQuery query1, CriteriaQuery... queries); - default JpaSubQuery unionAll(Subquery query1, Subquery... queries) { - return union( true, query1, queries ); - } - @Override + CriteriaSelect union(CriteriaSelect left, CriteriaSelect right); + JpaCriteriaQuery union(CriteriaQuery left, CriteriaQuery right); - @Override - default JpaCriteriaQuery unionAll(CriteriaQuery left, CriteriaQuery right) { - return null; - } - default JpaSubQuery union(Subquery query1, Subquery... queries) { return union( false, query1, queries ); } JpaSubQuery union(boolean all, Subquery query1, Subquery... queries); - @Override - JpaCriteriaQuery intersect(CriteriaQuery left, CriteriaQuery right); + default JpaSubQuery unionAll(Subquery query1, Subquery... queries) { + return union( true, query1, queries ); + } @Override + CriteriaSelect unionAll(CriteriaSelect left, CriteriaSelect right); + + JpaCriteriaQuery unionAll(CriteriaQuery left, CriteriaQuery right); + + @Override + CriteriaSelect intersect(CriteriaSelect left, CriteriaSelect right); + + @Override + CriteriaSelect intersectAll(CriteriaSelect left, CriteriaSelect right); + + JpaCriteriaQuery intersect(CriteriaQuery left, CriteriaQuery right); + JpaCriteriaQuery intersectAll(CriteriaQuery left, CriteriaQuery right); default JpaSubQuery intersectAll(Subquery query1, Subquery... queries) { @@ -211,9 +219,13 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder { JpaSubQuery intersect(boolean all, Subquery query1, Subquery... queries); @Override - JpaCriteriaQuery except(CriteriaQuery left, CriteriaQuery right); + CriteriaSelect except(CriteriaSelect left, CriteriaSelect right); @Override + CriteriaSelect exceptAll(CriteriaSelect left, CriteriaSelect right); + + JpaCriteriaQuery except(CriteriaQuery left, CriteriaQuery right); + JpaCriteriaQuery exceptAll(CriteriaQuery left, CriteriaQuery right); default JpaSubQuery exceptAll(Subquery query1, Subquery... queries) { @@ -368,11 +380,11 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder { @Override JpaCompoundSelection tuple(Selection... selections); - JpaCompoundSelection tuple(List> selections); + JpaCompoundSelection tuple(List> selections); @Override JpaCompoundSelection array(Selection... selections); - JpaCompoundSelection array(List> selections); + JpaCompoundSelection array(List> selections); JpaCompoundSelection array(Class resultClass, Selection... selections); JpaCompoundSelection array(Class resultClass, List> selections); diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaQuery.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaQuery.java index a00ce68ab7..9c4283d59c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaQuery.java @@ -25,7 +25,7 @@ import jakarta.persistence.metamodel.EntityType; * * @author Steve Ebersole */ -public interface JpaCriteriaQuery extends CriteriaQuery, JpaQueryableCriteria, JpaSelectCriteria { +public interface JpaCriteriaQuery extends CriteriaQuery, JpaQueryableCriteria, JpaSelectCriteria, JpaCriteriaSelect { /** * A query that returns the number of results of this query. diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaSelect.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaSelect.java new file mode 100644 index 0000000000..7f7a01d300 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaCriteriaSelect.java @@ -0,0 +1,23 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.query.criteria; + +import jakarta.persistence.criteria.CriteriaSelect; + +/** + * Extension of the JPA {@link CriteriaSelect}. + * + * @apiNote This is different from {@link JpaSelectCriteria}. JPA added + * {@link CriteriaSelect} in version 3.2 while {@link JpaSelectCriteria} has + * existed for many releases prior. JPA's {@link CriteriaSelect} is intended + * for supporting its newly added set operations (union, interest, except). + * + * @author Steve Ebersole + */ +public interface JpaCriteriaSelect extends CriteriaSelect { + +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaSubQuery.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaSubQuery.java index 2dbdb83e5e..8ded391baf 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaSubQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/JpaSubQuery.java @@ -25,7 +25,7 @@ import org.hibernate.query.sqm.FetchClauseType; /** * @author Steve Ebersole */ -public interface JpaSubQuery extends Subquery, JpaSelectCriteria, JpaExpression, JpaCteContainer { +public interface JpaSubQuery extends Subquery, JpaSelectCriteria, JpaCriteriaSelect, JpaExpression, JpaCteContainer { JpaSubQuery multiselect(Selection... selections); diff --git a/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java index b1bf710210..d5aaf1323a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/criteria/spi/HibernateCriteriaBuilderDelegate.java @@ -62,6 +62,7 @@ import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CollectionJoin; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.ListJoin; @@ -211,11 +212,21 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde return criteriaBuilder.except( all, query1, queries ); } + @Override + public CriteriaSelect union(CriteriaSelect left, CriteriaSelect right) { + return criteriaBuilder.union( left, right ); + } + @Override public JpaSubQuery unionAll(Subquery query1, Subquery... queries) { return criteriaBuilder.unionAll( query1, queries ); } + @Override + public CriteriaSelect unionAll(CriteriaSelect left, CriteriaSelect right) { + return criteriaBuilder.unionAll( left, right ); + } + @Override public JpaSubQuery union(Subquery query1, Subquery... queries) { return criteriaBuilder.union( query1, queries ); @@ -241,6 +252,16 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde return criteriaBuilder.intersect( all, query1, queries ); } + @Override + public CriteriaSelect except(CriteriaSelect left, CriteriaSelect right) { + return criteriaBuilder.except( left, right ); + } + + @Override + public CriteriaSelect exceptAll(CriteriaSelect left, CriteriaSelect right) { + return criteriaBuilder.exceptAll( left, right ); + } + @Override public JpaSubQuery exceptAll(Subquery query1, Subquery... queries) { return criteriaBuilder.exceptAll( query1, queries ); @@ -348,6 +369,16 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde return criteriaBuilder.unionAll( left, right ); } + @Override + public CriteriaSelect intersect(CriteriaSelect left, CriteriaSelect right) { + return criteriaBuilder.intersect( left, right ); + } + + @Override + public CriteriaSelect intersectAll(CriteriaSelect left, CriteriaSelect right) { + return criteriaBuilder.intersectAll( left, right ); + } + @Override public JpaCriteriaQuery intersect(CriteriaQuery left, CriteriaQuery right) { return criteriaBuilder.intersect( left, right ); @@ -409,7 +440,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde } @Override - public JpaCompoundSelection tuple(List> selections) { + public JpaCompoundSelection tuple(List> selections) { return criteriaBuilder.tuple( selections ); } @@ -419,7 +450,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde } @Override - public JpaCompoundSelection array(List> selections) { + public JpaCompoundSelection array(List> selections) { return criteriaBuilder.array( selections ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java index 8c6dea2c86..bc4d1bf984 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryProducerImplementor.java @@ -47,9 +47,8 @@ public interface QueryProducerImplementor extends QueryProducer { @Override @Deprecated @SuppressWarnings("rawtypes") NativeQueryImplementor createNativeQuery(String sqlString); - @SuppressWarnings("rawtypes") @Override - NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass); + NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass); @Override NativeQueryImplementor createNativeQuery(String sqlString, Class resultClass, String tableAlias); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java index 2d71b057b6..5cc9ce35e5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/NodeBuilder.java @@ -64,7 +64,6 @@ import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.ListJoin; import jakarta.persistence.criteria.MapJoin; -import jakarta.persistence.criteria.Nulls; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; @@ -636,13 +635,13 @@ public interface NodeBuilder extends HibernateCriteriaBuilder { JpaCompoundSelection tuple(Selection[] selections); @Override - JpaCompoundSelection tuple(List> selections); + JpaCompoundSelection tuple(List> selections); @Override JpaCompoundSelection array(Selection[] selections); @Override - JpaCompoundSelection array(List> selections); + JpaCompoundSelection array(List> selections); @Override SqmUpdateStatement createCriteriaUpdate(Class targetEntity); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java index a033ccfb14..ce568734bc 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java @@ -58,6 +58,7 @@ import org.hibernate.query.criteria.HibernateCriteriaBuilder; import org.hibernate.query.criteria.JpaCoalesce; import org.hibernate.query.criteria.JpaCompoundSelection; import org.hibernate.query.criteria.JpaCriteriaQuery; +import org.hibernate.query.criteria.JpaCriteriaSelect; import org.hibernate.query.criteria.JpaCteCriteriaAttribute; import org.hibernate.query.criteria.JpaExpression; import org.hibernate.query.criteria.JpaFunction; @@ -170,6 +171,7 @@ import org.hibernate.type.spi.TypeConfiguration; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CollectionJoin; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.CriteriaSelect; import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.ListJoin; @@ -406,16 +408,42 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, return setOperation( all ? SetOperator.EXCEPT_ALL : SetOperator.EXCEPT, query1, queries ); } + @Override + public JpaCriteriaSelect union(CriteriaSelect left, CriteriaSelect right) { + if ( left instanceof Subquery ) { + assert right instanceof Subquery; + //noinspection unchecked + return setOperation( SetOperator.UNION, (Subquery) left, (Subquery) right ); + } + //noinspection unchecked + return setOperation( SetOperator.UNION, (JpaCriteriaQuery) left, (JpaCriteriaQuery) right ); + } + @Override public JpaSubQuery union(boolean all, Subquery query1, Subquery... queries) { return setOperation( all ? SetOperator.UNION_ALL : SetOperator.UNION, query1, queries ); } + @Override + public CriteriaSelect unionAll(CriteriaSelect left, CriteriaSelect right) { + return null; + } + @Override public JpaSubQuery intersect(boolean all, Subquery query1, Subquery... queries) { return setOperation( all ? SetOperator.INTERSECT_ALL : SetOperator.INTERSECT, query1, queries ); } + @Override + public CriteriaSelect except(CriteriaSelect left, CriteriaSelect right) { + return null; + } + + @Override + public CriteriaSelect exceptAll(CriteriaSelect left, CriteriaSelect right) { + return null; + } + @Override public JpaSubQuery except(boolean all, Subquery query1, Subquery... queries) { return setOperation( all ? SetOperator.EXCEPT_ALL : SetOperator.EXCEPT, query1, queries ); @@ -557,6 +585,16 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, return createUnionSet( SetOperator.UNION_ALL, left, right ); } + @Override + public CriteriaSelect intersect(CriteriaSelect left, CriteriaSelect right) { + return null; + } + + @Override + public CriteriaSelect intersectAll(CriteriaSelect left, CriteriaSelect right) { + return null; + } + @SuppressWarnings({ "rawtypes", "unchecked" }) private static JpaCriteriaQuery createUnionSet( SetOperator operator, @@ -786,13 +824,18 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, @Override public JpaCompoundSelection tuple(Selection[] selections) { - //noinspection unchecked - return tuple( (List>) (List) Arrays.asList( selections ) ); + return tuple( Arrays.asList( selections ) ); } @Override - public JpaCompoundSelection tuple(List> selections) { - return null; + public JpaCompoundSelection tuple(List> selections) { + checkMultiselect( selections ); + //noinspection unchecked,rawtypes + return new SqmJpaCompoundSelection<>( + (List) selections, + getTypeConfiguration().getJavaTypeRegistry().getDescriptor( Tuple.class ), + this + ); } @Override @@ -825,13 +868,13 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, @Override public JpaCompoundSelection array(Selection[] selections) { - //noinspection unchecked - return array( (List>) (List) Arrays.asList( selections ) ); + return array( Arrays.asList( selections ) ); } @Override - public JpaCompoundSelection array(List> selections) { - return array( Object[].class, selections ); + public JpaCompoundSelection array(List> selections) { + //noinspection unchecked,rawtypes + return array( Object[].class, (List) selections ); } @Override @@ -842,7 +885,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, @Override public JpaCompoundSelection array(Class resultClass, List> selections) { - checkMultiselect( selections ); + //noinspection rawtypes,unchecked + checkMultiselect( (List) selections ); final JavaType javaType = getTypeConfiguration().getJavaTypeRegistry().getDescriptor( resultClass ); //noinspection unchecked return new SqmJpaCompoundSelection<>( (List>) selections, javaType, this ); @@ -856,7 +900,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, @Override public JpaCompoundSelection construct(Class resultClass, List> arguments) { - checkMultiselect( arguments ); + //noinspection unchecked,rawtypes + checkMultiselect( (List) arguments ); final SqmDynamicInstantiation instantiation; if ( List.class.equals( resultClass ) ) { //noinspection unchecked @@ -891,10 +936,11 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext, * "An argument to the multiselect method must not be a tuple- * or array-valued compound selection item." */ - void checkMultiselect(List> selections) { + void checkMultiselect(List> selections) { final HashSet aliases = new HashSet<>( CollectionHelper.determineProperSizing( selections.size() ) ); - for ( JpaSelection selection : selections ) { + for ( Selection it : selections ) { + final JpaSelection selection = (JpaSelection) it; if ( selection.isCompoundSelection() ) { if ( selection.getJavaType().isArray() ) { throw new IllegalArgumentException( diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java index b4c3a95c61..00c086d9dc 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelectStatement.java @@ -31,7 +31,6 @@ import org.hibernate.query.sqm.tree.predicate.SqmPredicate; import org.hibernate.query.sqm.tree.from.SqmRoot; import jakarta.persistence.Tuple; -import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Order; import jakarta.persistence.criteria.ParameterExpression; @@ -331,8 +330,8 @@ public class SqmSelectStatement extends AbstractSqmSelectQuery implements @SuppressWarnings("unchecked") private Selection getResultSelection(List selectionList) { final Class resultType = getResultType(); - final List> selections = - (List>) selectionList; + //noinspection rawtypes + final List> selections = (List) selectionList; if ( resultType == null || resultType == Object.class ) { switch ( selectionList.size() ) { case 0: { @@ -344,12 +343,12 @@ public class SqmSelectStatement extends AbstractSqmSelectQuery implements return (Selection) selectionList.get( 0 ); } default: { - return (Selection) nodeBuilder().array( selections ); + return (Selection) nodeBuilder().array( selectionList ); } } } else if ( Tuple.class.isAssignableFrom( resultType ) ) { - return (Selection) nodeBuilder().tuple( selections ); + return (Selection) nodeBuilder().tuple( selectionList ); } else if ( resultType.isArray() ) { return nodeBuilder().array( resultType, selections ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java index 1b5cdeb755..88d72de8df 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java @@ -41,7 +41,6 @@ import org.hibernate.query.sqm.tree.domain.SqmCorrelatedListJoin; import org.hibernate.query.sqm.tree.domain.SqmCorrelatedMapJoin; import org.hibernate.query.sqm.tree.domain.SqmCorrelatedRoot; import org.hibernate.query.sqm.tree.domain.SqmCorrelatedSetJoin; -import org.hibernate.query.sqm.tree.domain.SqmCorrelatedSingularJoin; import org.hibernate.query.sqm.tree.domain.SqmCorrelatedSingularValuedJoin; import org.hibernate.query.sqm.tree.domain.SqmCorrelation; import org.hibernate.query.sqm.tree.domain.SqmListJoin; @@ -49,7 +48,6 @@ import org.hibernate.query.sqm.tree.domain.SqmMapJoin; import org.hibernate.query.sqm.tree.domain.SqmSetJoin; import org.hibernate.query.sqm.tree.domain.SqmSingularValuedJoin; import org.hibernate.query.sqm.tree.expression.SqmExpression; -import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmCrossJoin; import org.hibernate.query.sqm.tree.from.SqmEntityJoin; import org.hibernate.query.sqm.tree.from.SqmFromClause; @@ -276,12 +274,12 @@ public class SqmSubQuery extends AbstractSqmSelectQuery implements SqmSele break; } default: { - resultSelection = ( Selection ) nodeBuilder().array( selections ); + resultSelection = ( Selection ) nodeBuilder().array( selectionList ); } } } else if ( Tuple.class.isAssignableFrom( resultType ) ) { - resultSelection = ( Selection ) nodeBuilder().tuple( selections ); + resultSelection = ( Selection ) nodeBuilder().tuple( selectionList ); } else if ( resultType.isArray() ) { resultSelection = nodeBuilder().array( resultType, selections ); diff --git a/local-build-plugins/src/main/java/org/hibernate/orm/env/JpaVersion.java b/local-build-plugins/src/main/java/org/hibernate/orm/env/JpaVersion.java index 90c7849ee1..1bf474e691 100644 --- a/local-build-plugins/src/main/java/org/hibernate/orm/env/JpaVersion.java +++ b/local-build-plugins/src/main/java/org/hibernate/orm/env/JpaVersion.java @@ -18,7 +18,7 @@ import org.gradle.api.initialization.Settings; public class JpaVersion { public static final String EXT_KEY = "jakartaJpaVersion"; public static final String VERSION_KEY = "jakartaJpaVersionOverride"; - public static final String DEFAULT_VERSION = "3.2.0-B01"; + public static final String DEFAULT_VERSION = "3.2.0-B02"; private final String name; private final String osgiName;