Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions hibernate-core/src/main/java/org/hibernate/SessionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.FindOption;
import jakarta.persistence.SynchronizationType;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.TypedQueryReference;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.engine.spi.SessionFactoryImplementor;
Expand Down Expand Up @@ -557,6 +559,27 @@ default boolean containsFetchProfileDefinition(String name) {
return getDefinedFilterNames().contains( name );
}

/**
* Add or override the definition of a named query, returning
* a {@linkplain TypedQueryReference reference} to the query.
* Settings such as first and max results, hints, flush mode,
* cache mode, timeout, and lock options are preserved as part
* of the named query definition. Any arguments bound to query
* parameters are discarded.
*
* @param name the name to be assigned to the query
* @param query the query, including first and max results, hints,
* flush mode, cache mode, timeout, and lock options
*
* @see #addNamedQuery(String, jakarta.persistence.Query)
* @see org.hibernate.query.QueryProducer#createQuery(TypedQueryReference)
* @see org.hibernate.query.QueryProducer#createSelectionQuery(String, Class)
*
* @since 7.0
*/
@Incubating
<R> TypedQueryReference<R> addNamedQuery(String name, TypedQuery<R> query);

/**
* The name assigned to this {@code SessionFactory}, if any.
* <ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import jakarta.persistence.PersistenceUnitUtil;
import jakarta.persistence.Query;
import jakarta.persistence.SynchronizationType;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.TypedQueryReference;

import org.hibernate.CustomEntityDirtinessStrategy;
Expand Down Expand Up @@ -158,7 +159,7 @@
}

@Override
public void addNamedQuery(String name, Query query) {

Check notice

Code scanning / CodeQL

Confusing overloading of methods Note

Method SessionFactoryDelegatingImpl.addNamedQuery(..) could be confused with overloaded method
addNamedQuery
, since dispatch depends on static types.
delegate.addNamedQuery( name, query );
}

Expand Down Expand Up @@ -416,4 +417,9 @@
public EventListenerRegistry getEventListenerRegistry() {
return delegate.getEventListenerRegistry();
}

@Override
public <R> TypedQueryReference<R> addNamedQuery(String name, TypedQuery<R> query) {
return delegate.addNamedQuery( name, query );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import javax.naming.Reference;
import javax.naming.StringRefAddr;

import jakarta.persistence.TypedQuery;
import org.hibernate.CustomEntityDirtinessStrategy;
import org.hibernate.EntityNameResolver;
import org.hibernate.FlushMode;
Expand Down Expand Up @@ -96,6 +97,7 @@
import org.hibernate.proxy.EntityNotFoundDelegate;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.query.internal.QueryEngineImpl;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sql.internal.SqlTranslationEngineImpl;
import org.hibernate.query.sql.spi.SqlTranslationEngine;
Expand Down Expand Up @@ -871,10 +873,19 @@

}

private NamedObjectRepository getNamedObjectRepository() {
validateNotClosed();
return getQueryEngine().getNamedObjectRepository();
}

@Override
public void addNamedQuery(String name, Query query) {

Check notice

Code scanning / CodeQL

Confusing overloading of methods Note

Method SessionFactoryImpl.addNamedQuery(..) could be confused with overloaded method
addNamedQuery
, since dispatch depends on static types.
validateNotClosed();
getQueryEngine().getNamedObjectRepository().registerNamedQuery( name, query );
getNamedObjectRepository().registerNamedQuery( name, query );
}

@Override
public <R> TypedQueryReference<R> addNamedQuery(String name, TypedQuery<R> query) {
return getNamedObjectRepository().registerNamedQuery( name, query );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import jakarta.persistence.PersistenceException;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.QueryException;
Expand Down Expand Up @@ -123,6 +124,23 @@ else if ( queryImplementor instanceof SqmQueryImplementor<?> sqmQueryImplementor
throw new PersistenceException( "Could not register named query: " + name );
}

@Override
public <R> TypedQueryReference<R> registerNamedQuery(String name, TypedQuery<R> query) {
if ( query instanceof NativeQueryImplementor<R> nativeQueryImplementor ) {
final NamedNativeQueryMemento<R> memento = nativeQueryImplementor.toMemento( name );
registerNativeQueryMemento( name, memento );
return memento;
}
else if ( query instanceof SqmQueryImplementor<R> sqmQueryImplementor ) {
final NamedSqmQueryMemento<R> memento = sqmQueryImplementor.toMemento( name );
registerSqmQueryMemento( name, memento );
return memento;
}
else {
throw new IllegalArgumentException( "unknown implementation of TypedQuery" );
}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named SQM Memento

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.function.Consumer;

import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
import org.hibernate.boot.Metadata;
Expand All @@ -34,8 +35,10 @@

<R> Map<String, TypedQueryReference<R>> getNamedQueries(Class<R> resultType);

void registerNamedQuery(String name, Query query);

Check notice

Code scanning / CodeQL

Confusing overloading of methods Note

Method NamedObjectRepository.registerNamedQuery(..) could be confused with overloaded method
registerNamedQuery
, since dispatch depends on static types.

<R> TypedQueryReference<R> registerNamedQuery(String name, TypedQuery<R> query);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named SQM Memento

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ public Class<R> getResultType() {
}

@Override
public NamedNativeQueryMemento<?> toMemento(String name) {
public NamedNativeQueryMemento<R> toMemento(String name) {
return new NamedNativeQueryMementoImpl<>(
name,
resultType != null ? resultType : extractResultClass( resultSetMapping ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ default <T> NativeQueryImplementor<T> setResultTransformer(ResultTransformer<T>
}

@Override
NamedNativeQueryMemento<?> toMemento(String name);
NamedNativeQueryMemento<R> toMemento(String name);

@Override
NativeQueryImplementor<R> addScalar(String columnAlias);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,7 @@ else if ( expectedResultClass.isArray() ) {
verifySelectionType( componentType, jpaCompliance, selection.getSelectableNode() );
}
}
//TODO: else check that the expectedResultClass has an appropriate constructor
}

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

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