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
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,16 @@ default Stream<R> stream() {
*/
SelectionQuery<R> setFollowOnLocking(boolean enable);

/**
* Set a {@link TupleTransformer}.
*/
<T> SelectionQuery<T> setTupleTransformer(TupleTransformer<T> transformer);

/**
* Set a {@link ResultListTransformer}.
*/
SelectionQuery<R> setResultListTransformer(ResultListTransformer<R> transformer);

@Override
SelectionQuery<R> setParameter(String name, Object value);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@
package org.hibernate.query.criteria.internal;

import java.io.Serializable;
import java.util.Locale;
import java.util.Map;

import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.LockOptions;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.IllegalSelectQueryException;
import org.hibernate.query.QueryTypeMismatchException;
import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.spi.QueryEngine;
Expand All @@ -21,6 +24,7 @@
import org.hibernate.query.sqm.tree.SqmStatement;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;

public class NamedCriteriaQueryMementoImpl<E> extends AbstractNamedQueryMemento<E>
implements NamedSqmQueryMemento<E>, Serializable {
Expand Down Expand Up @@ -60,12 +64,32 @@ public NamedCriteriaQueryMementoImpl(

@Override
public void validate(QueryEngine queryEngine) {
// nothing to do
}

private static <T> void checkResultType(Class<T> resultType, SqmSelectStatement<?> selectStatement) {
final Class<?> expectedResultType = selectStatement.getResultType();
if ( expectedResultType != null
&& !resultType.isAssignableFrom( expectedResultType ) ) {
throw new QueryTypeMismatchException(
String.format(
Locale.ROOT,
"Incorrect query result type: query produces '%s' but type '%s' was given",
expectedResultType.getName(),
resultType.getName()
)
);
}
}

@Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType) {
return new QuerySqmImpl<>( this, resultType, session );
if ( sqmStatement instanceof SqmSelectStatement<?> selectStatement ) {
checkResultType( resultType, selectStatement );
}
@SuppressWarnings("unchecked") // we just checked the result type
final SqmStatement<T> statement = (SqmStatement<T>) sqmStatement;
return new QuerySqmImpl<>( this, statement, resultType, session );
}

@Override
Expand All @@ -75,7 +99,13 @@ public SqmQueryImplementor<E> toQuery(SharedSessionContractImplementor session)

@Override
public <T> SqmSelectionQuery<T> toSelectionQuery(Class<T> resultType, SharedSessionContractImplementor session) {
return new SqmSelectionQueryImpl<>( this, resultType, session );
if ( !( sqmStatement instanceof SqmSelectStatement<?> selectStatement ) ) {
throw new IllegalSelectQueryException( "Named query is not a SELECT statement: " + getName() );
}
checkResultType( resultType, selectStatement );
@SuppressWarnings("unchecked") // we just checked the result type
final SqmSelectStatement<T> statement = (SqmSelectStatement<T>) selectStatement;
return new SqmSelectionQueryImpl<>( this, statement, resultType, session );
}

@Override
Expand Down Expand Up @@ -110,7 +140,7 @@ public Map<String, String> getParameterTypes() {

@Override
public NamedSqmQueryMemento<E> makeCopy(String name) {
return new NamedCriteriaQueryMementoImpl<E>(
return new NamedCriteriaQueryMementoImpl<>(
name,
getResultType(),
sqmStatement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@
*/
package org.hibernate.query.named;

import jakarta.persistence.Query;
import org.hibernate.Incubating;

/**
* Contract for Query impls that can be converted to a named query memento to be
* stored in the {@link NamedObjectRepository}
* Contract for {@linkplain org.hibernate.query.spi.QueryImplementor query implementations}
* which can be converted to {@linkplain NamedQueryMemento named query mementos} for storage
* in the {@link NamedObjectRepository}.
*
* @author Steve Ebersole
*
* @see NamedQueryMemento
*/
@Incubating
public interface NameableQuery {
/**
* Convert the query into the memento
* Convert this query into the memento.
*
* @see org.hibernate.SessionFactory#addNamedQuery(String, Query)
* @see NamedObjectRepository#registerNamedQuery(String, Query)
*/
NamedQueryMemento<?> toMemento(String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import org.hibernate.LockOptions;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.AvailableHints;
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
import org.hibernate.query.BindableType;
Expand Down Expand Up @@ -73,7 +71,6 @@
public abstract class AbstractQuery<R>
extends AbstractSelectionQuery<R>
implements QueryImplementor<R> {
protected static final CoreMessageLogger log = CoreLogging.messageLogger( AbstractQuery.class );

public AbstractQuery(SharedSessionContractImplementor session) {
super( session );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.query.sqm.internal.DomainParameterXref;
import org.hibernate.query.sqm.internal.SqmUtil;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;

import static org.hibernate.query.sqm.internal.SqmUtil.checkQueryReturnType;
import static org.hibernate.query.sqm.internal.SqmUtil.isResultTypeAlwaysAllowed;

/**
* @author Steve Ebersole
*/
Expand Down Expand Up @@ -48,9 +50,9 @@ public DomainParameterXref getDomainParameterXref() {
@Override
public void validateResultType(Class<?> resultType) {
assert sqmStatement instanceof SqmSelectStatement<?>;
if ( resultType != null && !SqmUtil.isResultTypeAlwaysAllowed( resultType ) ) {
if ( resultType != null && !isResultTypeAlwaysAllowed( resultType ) ) {
if ( !allowedReturnTypes.containsKey( resultType ) ) {
SqmUtil.checkQueryReturnType( ( (SqmSelectStatement<R>) sqmStatement ).getQueryPart(), resultType );
checkQueryReturnType( ( (SqmSelectStatement<R>) sqmStatement ).getQueryPart(), resultType );
allowedReturnTypes.put( resultType, Boolean.TRUE );
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.spi.NativeQueryConstructorTransformer;
import org.hibernate.jpa.spi.NativeQueryListTransformer;
import org.hibernate.jpa.spi.NativeQueryMapTransformer;
Expand Down Expand Up @@ -137,6 +139,9 @@
public class NativeQueryImpl<R>
extends AbstractQuery<R>
implements NativeQueryImplementor<R>, DomainQueryExecutionContext, ResultSetMappingResolutionContext {

private static final CoreMessageLogger log = CoreLogging.messageLogger( NativeQueryImpl.class );

private final String sqlString;
private final String originalSqlString;
private final ParameterMetadataImplementor parameterMetadata;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import org.hibernate.query.QueryFlushMode;
import org.hibernate.query.BindableType;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.ResultListTransformer;
import org.hibernate.query.SelectionQuery;
import org.hibernate.query.TupleTransformer;
import org.hibernate.query.spi.SqmQuery;

import jakarta.persistence.Parameter;
Expand Down Expand Up @@ -163,4 +165,10 @@ public interface SqmSelectionQuery<R> extends SqmQuery, SelectionQuery<R> {

@Override
SqmSelectionQuery<R> setReadOnly(boolean readOnly);

@Override
<T> SqmSelectionQuery<T> setTupleTransformer(TupleTransformer<T> transformer);

@Override
SqmSelectionQuery<R> setResultListTransformer(ResultListTransformer<R> transformer);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@
import org.hibernate.query.restriction.Restriction;
import org.hibernate.query.SelectionQuery;
import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.hql.internal.QuerySplitter;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.spi.AbstractSelectionQuery;
import org.hibernate.query.spi.HqlInterpretation;
import org.hibernate.query.spi.MutableQueryOptions;
import org.hibernate.query.spi.ParameterMetadataImplementor;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.SelectQueryPlan;
Expand All @@ -35,11 +34,9 @@
import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
import org.hibernate.query.sqm.tree.select.SqmSelection;
import org.hibernate.sql.results.internal.TupleMetadata;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;

import java.util.List;
import java.util.Map;

import jakarta.persistence.TupleElement;
import jakarta.persistence.criteria.CompoundSelection;
Expand Down Expand Up @@ -113,8 +110,7 @@ protected void errorOrLogForPaginationWithCollectionFetch() {
public abstract TupleMetadata getTupleMetadata();

private SqmSelectStatement<R> getSqmSelectStatement() {
final SqmStatement<R> sqmStatement = getSqmStatement();
if ( sqmStatement instanceof SqmSelectStatement<R> selectStatement ) {
if ( getSqmStatement() instanceof SqmSelectStatement<R> selectStatement ) {
return selectStatement;
}
else {
Expand Down Expand Up @@ -172,10 +168,10 @@ public KeyedResultList<R> getKeyedResultList(KeyedPage<R> keyedPage) {
final List<KeyedResult<R>> results =
new SqmSelectionQueryImpl<KeyedResult<R>>( this, keyedPage )
.getResultList();
final Page page = keyedPage.getPage();
final int pageSize = keyedPage.getPage().getSize();
return new KeyedResultList<>(
collectResults( results, page.getSize(), keyedPage.getKeyInterpretation() ),
collectKeys( results, page.getSize() ),
collectResults( results, pageSize, keyedPage.getKeyInterpretation() ),
collectKeys( results, pageSize ),
keyedPage,
nextPage( keyedPage, results ),
previousPage( keyedPage, results )
Expand Down Expand Up @@ -256,8 +252,8 @@ protected <T> ConcreteSqmSelectQueryPlan<T> buildConcreteQueryPlan(
);
}

protected void applyOptions(NamedSqmQueryMemento<?> memento) {
applyOptions( (NamedQueryMemento<?>) memento );
protected void applySqmOptions(NamedSqmQueryMemento<?> memento) {
applyOptions( memento );

if ( memento.getFirstResult() != null ) {
setFirstResult( memento.getFirstResult() );
Expand All @@ -270,12 +266,10 @@ protected void applyOptions(NamedSqmQueryMemento<?> memento) {
if ( memento.getParameterTypes() != null ) {
final BasicTypeRegistry basicTypeRegistry =
getSessionFactory().getTypeConfiguration().getBasicTypeRegistry();
for ( Map.Entry<String, String> entry : memento.getParameterTypes().entrySet() ) {
final BasicType<?> type =
basicTypeRegistry.getRegisteredType( entry.getValue() );
getParameterMetadata()
.getQueryParameter( entry.getKey() ).applyAnticipatedType( type );
}
final ParameterMetadataImplementor parameterMetadata = getParameterMetadata();
memento.getParameterTypes().forEach( (key, value) ->
parameterMetadata.getQueryParameter( key )
.applyAnticipatedType( basicTypeRegistry.getRegisteredType( value ) ) );
}
}

Expand Down Expand Up @@ -393,7 +387,7 @@ else if ( queryPart instanceof SqmQueryGroup<?> queryGroup ) {
}

protected static <T> HqlInterpretation<T> interpretation(
NamedHqlQueryMementoImpl<?> memento,
NamedSqmQueryMemento<?> memento,
Class<T> expectedResultType,
SharedSessionContractImplementor session) {
final QueryEngine queryEngine = session.getFactory().getQueryEngine();
Expand Down
Loading