Skip to content

Commit b2b179a

Browse files
committed
HHH-19327 overload addNamedQuery() to take TypedQuery and return TypedQueryReference
1 parent a8f235e commit b2b179a

File tree

8 files changed

+70
-7
lines changed

8 files changed

+70
-7
lines changed

hibernate-core/src/main/java/org/hibernate/SessionFactory.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import jakarta.persistence.EntityManagerFactory;
1010
import jakarta.persistence.FindOption;
1111
import jakarta.persistence.SynchronizationType;
12+
import jakarta.persistence.TypedQuery;
13+
import jakarta.persistence.TypedQueryReference;
1214
import org.hibernate.boot.spi.SessionFactoryOptions;
1315
import org.hibernate.engine.spi.FilterDefinition;
1416
import org.hibernate.engine.spi.SessionFactoryImplementor;
@@ -557,6 +559,27 @@ default boolean containsFetchProfileDefinition(String name) {
557559
return getDefinedFilterNames().contains( name );
558560
}
559561

562+
/**
563+
* Add or override the definition of a named query, returning
564+
* a {@linkplain TypedQueryReference reference} to the query.
565+
* Settings such as first and max results, hints, flush mode,
566+
* cache mode, timeout, and lock options are preserved as part
567+
* of the named query definition. Any arguments bound to query
568+
* parameters are discarded.
569+
*
570+
* @param name the name to be assigned to the query
571+
* @param query the query, including first and max results, hints,
572+
* flush mode, cache mode, timeout, and lock options
573+
*
574+
* @see #addNamedQuery(String, jakarta.persistence.Query)
575+
* @see org.hibernate.query.QueryProducer#createQuery(TypedQueryReference)
576+
* @see org.hibernate.query.QueryProducer#createSelectionQuery(String, Class)
577+
*
578+
* @since 7.0
579+
*/
580+
@Incubating
581+
<R> TypedQueryReference<R> addNamedQuery(String name, TypedQuery<R> query);
582+
560583
/**
561584
* The name assigned to this {@code SessionFactory}, if any.
562585
* <ul>

hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import jakarta.persistence.PersistenceUnitUtil;
2020
import jakarta.persistence.Query;
2121
import jakarta.persistence.SynchronizationType;
22+
import jakarta.persistence.TypedQuery;
2223
import jakarta.persistence.TypedQueryReference;
2324

2425
import org.hibernate.CustomEntityDirtinessStrategy;
@@ -416,4 +417,9 @@ public ManagedBeanRegistry getManagedBeanRegistry() {
416417
public EventListenerRegistry getEventListenerRegistry() {
417418
return delegate.getEventListenerRegistry();
418419
}
420+
421+
@Override
422+
public <R> TypedQueryReference<R> addNamedQuery(String name, TypedQuery<R> query) {
423+
return delegate.addNamedQuery( name, query );
424+
}
419425
}

hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import javax.naming.Reference;
2626
import javax.naming.StringRefAddr;
2727

28+
import jakarta.persistence.TypedQuery;
2829
import org.hibernate.CustomEntityDirtinessStrategy;
2930
import org.hibernate.EntityNameResolver;
3031
import org.hibernate.FlushMode;
@@ -96,6 +97,7 @@
9697
import org.hibernate.proxy.EntityNotFoundDelegate;
9798
import org.hibernate.proxy.LazyInitializer;
9899
import org.hibernate.query.internal.QueryEngineImpl;
100+
import org.hibernate.query.named.NamedObjectRepository;
99101
import org.hibernate.query.spi.QueryEngine;
100102
import org.hibernate.query.sql.internal.SqlTranslationEngineImpl;
101103
import org.hibernate.query.sql.spi.SqlTranslationEngine;
@@ -871,10 +873,19 @@ public PersistenceUnitTransactionType getTransactionType() {
871873

872874
}
873875

876+
private NamedObjectRepository getNamedObjectRepository() {
877+
validateNotClosed();
878+
return getQueryEngine().getNamedObjectRepository();
879+
}
880+
874881
@Override
875882
public void addNamedQuery(String name, Query query) {
876-
validateNotClosed();
877-
getQueryEngine().getNamedObjectRepository().registerNamedQuery( name, query );
883+
getNamedObjectRepository().registerNamedQuery( name, query );
884+
}
885+
886+
@Override
887+
public <R> TypedQueryReference<R> addNamedQuery(String name, TypedQuery<R> query) {
888+
return getNamedObjectRepository().registerNamedQuery( name, query );
878889
}
879890

880891
@Override

hibernate-core/src/main/java/org/hibernate/query/internal/NamedObjectRepositoryImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import jakarta.persistence.PersistenceException;
1212
import jakarta.persistence.Query;
13+
import jakarta.persistence.TypedQuery;
1314
import org.hibernate.AssertionFailure;
1415
import org.hibernate.HibernateException;
1516
import org.hibernate.QueryException;
@@ -123,6 +124,23 @@ else if ( queryImplementor instanceof SqmQueryImplementor<?> sqmQueryImplementor
123124
throw new PersistenceException( "Could not register named query: " + name );
124125
}
125126

127+
@Override
128+
public <R> TypedQueryReference<R> registerNamedQuery(String name, TypedQuery<R> query) {
129+
if ( query instanceof NativeQueryImplementor<R> nativeQueryImplementor ) {
130+
final NamedNativeQueryMemento<R> memento = nativeQueryImplementor.toMemento( name );
131+
registerNativeQueryMemento( name, memento );
132+
return memento;
133+
}
134+
else if ( query instanceof SqmQueryImplementor<R> sqmQueryImplementor ) {
135+
final NamedSqmQueryMemento<R> memento = sqmQueryImplementor.toMemento( name );
136+
registerSqmQueryMemento( name, memento );
137+
return memento;
138+
}
139+
else {
140+
throw new IllegalArgumentException( "unknown implementation of TypedQuery" );
141+
}
142+
}
143+
126144
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127145
// Named SQM Memento
128146

hibernate-core/src/main/java/org/hibernate/query/named/NamedObjectRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.function.Consumer;
99

1010
import jakarta.persistence.Query;
11+
import jakarta.persistence.TypedQuery;
1112
import org.hibernate.HibernateException;
1213
import org.hibernate.Incubating;
1314
import org.hibernate.boot.Metadata;
@@ -36,6 +37,8 @@ public interface NamedObjectRepository {
3637

3738
void registerNamedQuery(String name, Query query);
3839

40+
<R> TypedQueryReference<R> registerNamedQuery(String name, TypedQuery<R> query);
41+
3942
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4043
// Named SQM Memento
4144

hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ public Class<R> getResultType() {
523523
}
524524

525525
@Override
526-
public NamedNativeQueryMemento<?> toMemento(String name) {
526+
public NamedNativeQueryMemento<R> toMemento(String name) {
527527
return new NamedNativeQueryMementoImpl<>(
528528
name,
529529
resultType != null ? resultType : extractResultClass( resultSetMapping ),

hibernate-core/src/main/java/org/hibernate/query/sql/spi/NativeQueryImplementor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ default <T> NativeQueryImplementor<T> setResultTransformer(ResultTransformer<T>
6060
}
6161

6262
@Override
63-
NamedNativeQueryMemento<?> toMemento(String name);
63+
NamedNativeQueryMemento<R> toMemento(String name);
6464

6565
@Override
6666
NativeQueryImplementor<R> addScalar(String columnAlias);

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,7 @@ else if ( expectedResultClass.isArray() ) {
10721072
verifySelectionType( componentType, jpaCompliance, selection.getSelectableNode() );
10731073
}
10741074
}
1075+
//TODO: else check that the expectedResultClass has an appropriate constructor
10751076
}
10761077

10771078
/**
@@ -1221,9 +1222,10 @@ private static boolean isMatchingDateJdbcType(Class<?> resultClass, JdbcType jdb
12211222

12221223
private static void throwQueryTypeMismatchException(Class<?> resultClass, SqmExpressible<?> sqmExpressible) {
12231224
throw new QueryTypeMismatchException( String.format(
1224-
"Specified result type [%s] did not match Query selection type [%s] - multiple selections: use Tuple or array",
1225-
resultClass.getName(),
1226-
sqmExpressible.getTypeName()
1225+
Locale.ROOT,
1226+
"Incorrect query result type: query produces '%s' but type '%s' was given",
1227+
sqmExpressible.getTypeName(),
1228+
resultClass.getName()
12271229
) );
12281230
}
12291231
}

0 commit comments

Comments
 (0)