diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java index 0f231ff63..68c0e0619 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/Mutiny.java @@ -5,11 +5,6 @@ */ package org.hibernate.reactive.mutiny; -import java.lang.invoke.MethodHandles; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; - import org.hibernate.Cache; import org.hibernate.CacheMode; import org.hibernate.Filter; @@ -43,12 +38,17 @@ import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.Parameter; +import jakarta.persistence.TypedQueryReference; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.metamodel.Attribute; import jakarta.persistence.metamodel.Metamodel; +import java.lang.invoke.MethodHandles; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; import static org.hibernate.engine.internal.ManagedTypeHelper.asPersistentAttributeInterceptable; import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttributeInterceptable; @@ -994,6 +994,22 @@ default Uni lock(Object entity, LockModeType lockModeType) { */ MutationQuery createMutationQuery(JpaCriteriaInsert insert); + /** + * Create a typed {@link org.hibernate.query.Query} instance for the given typed query reference. + * + * @param typedQueryReference the type query reference + * + * @return The {@link org.hibernate.query.Query} instance for execution + * + * @throws IllegalArgumentException if a query has not been + * defined with the name of the typed query reference or if + * the query result is found to not be assignable to + * result class of the typed query reference + * + * @see org.hibernate.query.QueryProducer#createQuery(TypedQueryReference) + */ + Query createQuery(TypedQueryReference typedQueryReference); + /** * Create an instance of {@link Query} for the given HQL/JPQL query * string or HQL/JPQL update or delete statement. In the case of an diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionImpl.java index 87cf50bb0..ab57ee718 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionImpl.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/mutiny/impl/MutinySessionImpl.java @@ -12,6 +12,7 @@ import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.PersistenceException; +import jakarta.persistence.TypedQueryReference; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaUpdate; @@ -34,6 +35,7 @@ import org.hibernate.reactive.mutiny.Mutiny.Query; import org.hibernate.reactive.mutiny.Mutiny.SelectionQuery; import org.hibernate.reactive.pool.ReactiveConnection; +import org.hibernate.reactive.query.ReactiveQuery; import org.hibernate.reactive.session.ReactiveConnectionSupplier; import org.hibernate.reactive.session.ReactiveQueryProducer; import org.hibernate.reactive.session.ReactiveSession; @@ -140,6 +142,12 @@ public MutationQuery createMutationQuery(JpaCriteriaInsert insert) { return new MutinyMutationQueryImpl<>( delegate.createReactiveMutationQuery( insert ), factory ); } + @Override + public Query createQuery(TypedQueryReference typedQueryReference) { + ReactiveQuery reactiveQuery = delegate.createReactiveQuery( typedQueryReference ); + return new MutinyQueryImpl<>( reactiveQuery, factory ); + } + @Override @Deprecated public Query createQuery(String queryString) { return new MutinyQueryImpl<>( delegate.createReactiveQuery( queryString ), factory ); diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/ReactiveQueryProducer.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/ReactiveQueryProducer.java index a3b667fea..c9a7cc11b 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/ReactiveQueryProducer.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/ReactiveQueryProducer.java @@ -5,6 +5,7 @@ */ package org.hibernate.reactive.session; +import jakarta.persistence.TypedQueryReference; import java.util.concurrent.CompletionStage; import org.hibernate.Incubating; @@ -53,6 +54,8 @@ public interface ReactiveQueryProducer extends ReactiveConnectionSupplier { ReactiveQuery createReactiveQuery(String queryString); + ReactiveQuery createReactiveQuery(TypedQueryReference typedQueryReference); + ReactiveQuery createReactiveQuery(CriteriaQuery criteriaQuery); ReactiveQuery createReactiveQuery(String queryString, Class resultType); diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveSessionImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveSessionImpl.java index 72157e46e..468093305 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveSessionImpl.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveSessionImpl.java @@ -5,6 +5,7 @@ */ package org.hibernate.reactive.session.impl; +import jakarta.persistence.TypedQueryReference; import java.lang.invoke.MethodHandles; import java.util.List; import java.util.Map; @@ -357,6 +358,21 @@ protected ReactiveQueryImplementor createReactiveCriteriaQuery(SqmStateme return query; } + @Override + public ReactiveQuery createReactiveQuery(TypedQueryReference typedQueryReference) { + checksBeforeQueryCreation(); + @SuppressWarnings("unchecked") + // this cast is fine because of all our impls of TypedQueryReference return Class + final Class resultType = (Class) typedQueryReference.getResultType(); + ReactiveQueryImplementor query = (ReactiveQueryImplementor) buildNamedQuery( + typedQueryReference.getName(), + memento -> createSqmQueryImplementor( resultType, memento ), + memento -> createNativeQueryImplementor( resultType, memento ) + ); + typedQueryReference.getHints().forEach( query::setHint ); + return query; + } + @Override public ReactiveQuery createReactiveQuery(String queryString) { return createReactiveQuery( queryString, null ); diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveStatelessSessionImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveStatelessSessionImpl.java index 2d3efe4f5..c8fc602bc 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveStatelessSessionImpl.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveStatelessSessionImpl.java @@ -5,6 +5,7 @@ */ package org.hibernate.reactive.session.impl; +import jakarta.persistence.TypedQueryReference; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -830,6 +831,21 @@ public RootGraphImplementor getEntityGraph(Class entity, String name) return (RootGraphImplementor) entityGraph; } + @Override + public ReactiveQuery createReactiveQuery(TypedQueryReference typedQueryReference) { + checksBeforeQueryCreation(); + @SuppressWarnings("unchecked") + // this cast is fine because of all our impls of TypedQueryReference return Class + final Class resultType = (Class) typedQueryReference.getResultType(); + ReactiveQueryImplementor query = (ReactiveQueryImplementor) buildNamedQuery( + typedQueryReference.getName(), + memento -> createSqmQueryImplementor( resultType, memento ), + memento -> createNativeQueryImplementor( resultType, memento ) + ); + typedQueryReference.getHints().forEach( query::setHint ); + return query; + } + @Override public ReactiveSqmQueryImplementor createReactiveQuery(String queryString) { return createReactiveQuery( queryString, null ); diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java index 601b17c11..10f26fa2c 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/Stage.java @@ -5,6 +5,7 @@ */ package org.hibernate.reactive.stage; +import jakarta.persistence.TypedQueryReference; import java.lang.invoke.MethodHandles; import java.util.List; import java.util.concurrent.CompletionStage; @@ -26,6 +27,7 @@ import org.hibernate.proxy.HibernateProxy; import org.hibernate.query.Order; import org.hibernate.query.Page; +import org.hibernate.query.Query; import org.hibernate.query.criteria.HibernateCriteriaBuilder; import org.hibernate.query.criteria.JpaCriteriaInsert; import org.hibernate.reactive.common.AffectedEntities; @@ -885,17 +887,6 @@ default CompletionStage lock(Object entity, LockModeType lockModeType) { return lock( entity, convertToLockMode(lockModeType) ); } -// /** -// * Obtain the specified lock level upon the given object, with the given -// * {@link LockOptions}. -// * -// * @param entity a managed persistent instance -// * @param lockOptions the requested {@link LockOptions} -// * -// * @throws IllegalArgumentException if the given instance is not managed -// */ -// CompletionStage lock(Object entity, LockOptions lockOptions); - /** * Force this session to flush asynchronously. Must be called at the * end of a unit of work, before committing the transaction and closing @@ -1028,6 +1019,22 @@ default CompletionStage lock(Object entity, LockModeType lockModeType) { */ MutationQuery createMutationQuery(JpaCriteriaInsert insert); + /** + * Create a typed {@link org.hibernate.query.Query} instance for the given typed query reference. + * + * @param typedQueryReference the type query reference + * + * @return The {@link org.hibernate.query.Query} instance for execution + * + * @throws IllegalArgumentException if a query has not been + * defined with the name of the typed query reference or if + * the query result is found to not be assignable to + * result class of the typed query reference + * + * @see org.hibernate.query.QueryProducer#createQuery(TypedQueryReference) + */ + Query createQuery(TypedQueryReference typedQueryReference); + /** * Create an instance of {@link Query} for the given HQL/JPQL query * string or HQL/JPQL update or delete statement. In the case of an diff --git a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSessionImpl.java b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSessionImpl.java index 150c2ec96..dd25105f1 100644 --- a/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSessionImpl.java +++ b/hibernate-reactive-core/src/main/java/org/hibernate/reactive/stage/impl/StageSessionImpl.java @@ -5,6 +5,7 @@ */ package org.hibernate.reactive.stage.impl; +import jakarta.persistence.TypedQueryReference; import java.lang.invoke.MethodHandles; import java.util.List; import java.util.concurrent.CompletionStage; @@ -26,6 +27,7 @@ import org.hibernate.reactive.logging.impl.Log; import org.hibernate.reactive.logging.impl.LoggerFactory; import org.hibernate.reactive.pool.ReactiveConnection; +import org.hibernate.reactive.query.ReactiveQuery; import org.hibernate.reactive.session.ReactiveConnectionSupplier; import org.hibernate.reactive.session.ReactiveQueryProducer; import org.hibernate.reactive.session.ReactiveSession; @@ -530,6 +532,12 @@ public EntityGraph createEntityGraph(Class rootType, String graphName) return delegate.createEntityGraph( rootType, graphName ); } + @Override + public Query createQuery(TypedQueryReference typedQueryReference) { + ReactiveQuery reactiveQuery = delegate.createReactiveQuery( typedQueryReference ); + return new StageQueryImpl<>( reactiveQuery ); + } + @Override @Deprecated public Query createQuery(String queryString) { return new StageQueryImpl<>( delegate.createReactiveQuery( queryString ) );