Implemented NamedQuery creation from Criteria

This commit is contained in:
Andrea Boriero 2022-01-31 17:00:42 +01:00 committed by Andrea Boriero
parent bd5b05cbe3
commit eb572376a9
19 changed files with 414 additions and 224 deletions

View File

@ -55,11 +55,11 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.procedure.spi.NamedCallableQueryMemento;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.internal.NamedObjectRepositoryImpl; import org.hibernate.query.internal.NamedObjectRepositoryImpl;
import org.hibernate.query.named.NamedObjectRepository; import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
@ -346,8 +346,8 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
); );
} }
private Map<String, NamedHqlQueryMemento> buildNamedHqlMementos(SessionFactoryImplementor sessionFactory) { private Map<String, NamedSqmQueryMemento> buildNamedSqmMementos(SessionFactoryImplementor sessionFactory) {
final HashMap<String, NamedHqlQueryMemento> map = new HashMap<>(); final HashMap<String, NamedSqmQueryMemento> map = new HashMap<>();
if ( namedQueryMap != null ) { if ( namedQueryMap != null ) {
namedQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) ); namedQueryMap.forEach( (key, value) -> map.put( key, value.resolve( sessionFactory ) ) );
} }

View File

@ -15,7 +15,7 @@ import org.hibernate.boot.spi.AbstractNamedQueryDefinition;
import org.hibernate.boot.query.NamedHqlQueryDefinition; import org.hibernate.boot.query.NamedHqlQueryDefinition;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
@ -67,7 +67,7 @@ public class NamedHqlQueryDefinitionImpl extends AbstractNamedQueryDefinition im
} }
@Override @Override
public NamedHqlQueryMemento resolve(SessionFactoryImplementor factory) { public NamedSqmQueryMemento resolve(SessionFactoryImplementor factory) {
return new NamedHqlQueryMementoImpl( return new NamedHqlQueryMementoImpl(
getRegistrationName(), getRegistrationName(),
hqlString, hqlString,

View File

@ -11,7 +11,7 @@ import java.util.Map;
import org.hibernate.boot.internal.NamedHqlQueryDefinitionImpl; import org.hibernate.boot.internal.NamedHqlQueryDefinitionImpl;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
/** /**
* Boot-time descriptor of a named HQL query, as defined in * Boot-time descriptor of a named HQL query, as defined in
@ -27,7 +27,7 @@ public interface NamedHqlQueryDefinition extends NamedQueryDefinition {
String getHqlString(); String getHqlString();
@Override @Override
NamedHqlQueryMemento resolve(SessionFactoryImplementor factory); NamedSqmQueryMemento resolve(SessionFactoryImplementor factory);
class Builder extends AbstractNamedQueryBuilder<Builder> { class Builder extends AbstractNamedQueryBuilder<Builder> {
private String hqlString; private String hqlString;

View File

@ -68,8 +68,8 @@ import org.hibernate.query.QueryTypeMismatchException;
import org.hibernate.query.SelectionQuery; import org.hibernate.query.SelectionQuery;
import org.hibernate.query.UnknownNamedQueryException; import org.hibernate.query.UnknownNamedQueryException;
import org.hibernate.query.criteria.HibernateCriteriaBuilder; import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.hql.spi.SqmQueryImplementor; import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.spi.HqlInterpretation; import org.hibernate.query.spi.HqlInterpretation;
import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryEngine;
@ -82,6 +82,7 @@ import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.internal.QuerySqmImpl; import org.hibernate.query.sqm.internal.QuerySqmImpl;
import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl; import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl;
import org.hibernate.query.sqm.internal.SqmUtil; import org.hibernate.query.sqm.internal.SqmUtil;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmDmlStatement; import org.hibernate.query.sqm.tree.SqmDmlStatement;
import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement; import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
@ -872,12 +873,12 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
// this method can be called for either a named HQL query or a named native query // this method can be called for either a named HQL query or a named native query
// first see if it is a named HQL query // first see if it is a named HQL query
final NamedHqlQueryMemento namedHqlDescriptor = getFactory().getQueryEngine() final NamedSqmQueryMemento namedHqlDescriptor = getFactory().getQueryEngine()
.getNamedObjectRepository() .getNamedObjectRepository()
.getHqlQueryMemento( queryName ); .getSqmQueryMemento( queryName );
if ( namedHqlDescriptor != null ) { if ( namedHqlDescriptor != null ) {
return createNamedHqlSelectionQuery( namedHqlDescriptor, expectedResultType ); return createNamedSqmSelectionQuery( namedHqlDescriptor, expectedResultType );
} }
@ -906,13 +907,13 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
); );
} }
private <R> SqmSelectionQueryImpl<R> createNamedHqlSelectionQuery( private <R> SqmSelectionQuery<R> createNamedSqmSelectionQuery(
NamedHqlQueryMemento memento, NamedSqmQueryMemento memento,
Class<R> expectedResultType) { Class<R> expectedResultType) {
final SqmSelectionQueryImpl<R> selectionQuery = new SqmSelectionQueryImpl<>( memento, expectedResultType, this ); final SqmSelectionQuery<R> selectionQuery = memento.toSelectionQuery( expectedResultType, this );
if ( StringHelper.isEmpty( memento.getComment() ) ) { if ( StringHelper.isEmpty( memento.getComment() ) ) {
selectionQuery.setComment( "Named HQL query : " + memento.getRegistrationName() ); selectionQuery.setComment( "Named query : " + memento.getRegistrationName() );
} }
else { else {
selectionQuery.setComment( memento.getComment() ); selectionQuery.setComment( memento.getComment() );
@ -958,7 +959,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
final SqmQueryImplementor query = memento.toQuery( this, resultType ); final SqmQueryImplementor query = memento.toQuery( this, resultType );
if ( StringHelper.isEmpty( query.getComment() ) ) { if ( StringHelper.isEmpty( query.getComment() ) ) {
query.setComment( "dynamic HQL query" ); query.setComment( "dynamic query" );
} }
applyQuerySettingsAndHints( query ); applyQuerySettingsAndHints( query );
if ( memento.getLockOptions() != null ) { if ( memento.getLockOptions() != null ) {
@ -1002,7 +1003,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
protected QueryImplementor buildNamedQuery( protected QueryImplementor buildNamedQuery(
String queryName, String queryName,
Function<NamedHqlQueryMemento, SqmQueryImplementor> namedHqlHandler, Function<NamedSqmQueryMemento, SqmQueryImplementor> namedSqmHandler,
Function<NamedNativeQueryMemento, NativeQueryImplementor> namedNativeHandler) { Function<NamedNativeQueryMemento, NativeQueryImplementor> namedNativeHandler) {
checkOpen(); checkOpen();
pulseTransactionCoordinator(); pulseTransactionCoordinator();
@ -1011,17 +1012,17 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
// this method can be called for either a named HQL query or a named native query // this method can be called for either a named HQL query or a named native query
// first see if it is a named HQL query // first see if it is a named HQL query
final NamedHqlQueryMemento namedHqlDescriptor = getFactory().getQueryEngine() final NamedObjectRepository namedObjectRepository = getFactory().getQueryEngine()
.getNamedObjectRepository() .getNamedObjectRepository();
.getHqlQueryMemento( queryName );
if ( namedHqlDescriptor != null ) {
return namedHqlHandler.apply( namedHqlDescriptor ); final NamedSqmQueryMemento namedSqmQueryMemento = namedObjectRepository.getSqmQueryMemento( queryName );
if ( namedSqmQueryMemento != null ) {
return namedSqmHandler.apply( namedSqmQueryMemento );
} }
// otherwise, see if it is a named native query // otherwise, see if it is a named native query
final NamedNativeQueryMemento namedNativeDescriptor = getFactory().getQueryEngine() final NamedNativeQueryMemento namedNativeDescriptor = namedObjectRepository
.getNamedObjectRepository()
.getNativeQueryMemento( queryName ); .getNativeQueryMemento( queryName );
if ( namedNativeDescriptor != null ) { if ( namedNativeDescriptor != null ) {
@ -1086,17 +1087,17 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
public MutationQuery createNamedMutationQuery(String queryName) { public MutationQuery createNamedMutationQuery(String queryName) {
return buildNamedQuery( return buildNamedQuery(
queryName, queryName,
(hqlMemento) -> { (sqmMemento) -> {
final SqmQueryImplementor<?> query = hqlMemento.toQuery( this ); final SqmQueryImplementor<?> query = sqmMemento.toQuery( this );
final SqmStatement<?> sqmStatement = query.getSqmStatement(); final SqmStatement<?> sqmStatement = query.getSqmStatement();
if ( !( sqmStatement instanceof SqmDmlStatement ) ) { if ( !( sqmStatement instanceof SqmDmlStatement ) ) {
throw new IllegalMutationQueryException( throw new IllegalMutationQueryException(
"Expecting a named mutation query (" + queryName + "), but found `" + hqlMemento.getHqlString() + "`" "Expecting a named mutation query (" + queryName + "), but found a select statement"
); );
} }
if ( hqlMemento.getLockOptions() != null && ! hqlMemento.getLockOptions().isEmpty() ) { if ( sqmMemento.getLockOptions() != null && ! sqmMemento.getLockOptions().isEmpty() ) {
throw new IllegalNamedQueryOptionsException( throw new IllegalNamedQueryOptionsException(
"Named mutation query `" + queryName + "` specified lock-options" "Named mutation query `" + queryName + "` specified lock-options"
); );

View File

@ -106,10 +106,12 @@ import org.hibernate.proxy.LazyInitializer;
import org.hibernate.query.QueryLogging; import org.hibernate.query.QueryLogging;
import org.hibernate.query.hql.spi.SqmQueryImplementor; import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.NamedObjectRepository; import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.sql.spi.NativeQueryImplementor; import org.hibernate.query.sql.spi.NativeQueryImplementor;
import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.hibernate.resource.jdbc.spi.StatementInspector; import org.hibernate.resource.jdbc.spi.StatementInspector;
import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ExceptionMapper; import org.hibernate.resource.transaction.backend.jta.internal.synchronization.ExceptionMapper;
@ -871,9 +873,11 @@ public class SessionFactoryImpl implements SessionFactoryImplementor {
} }
else { else {
namedObjectRepository.registerHqlQueryMemento( final NamedQueryMemento namedQueryMemento = ( (SqmQueryImplementor<?>) hibernateQuery ).toMemento(
name );
namedObjectRepository.registerSqmQueryMemento(
name, name,
( (SqmQueryImplementor<?>) hibernateQuery ).toMemento( name ) (NamedSqmQueryMemento) namedQueryMemento
); );
} }
return; return;

View File

@ -0,0 +1,134 @@
/*
* 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.internal;
import java.io.Serializable;
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.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.internal.QuerySqmImpl;
import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmStatement;
public class NamedCriteriaQueryMementoImpl extends AbstractNamedQueryMemento implements NamedSqmQueryMemento, Serializable {
private final SqmStatement sqmStatement;
private final Integer firstResult;
private final Integer maxResults;
private final LockOptions lockOptions;
private final Map<String, String> parameterTypes;
public NamedCriteriaQueryMementoImpl(
String name,
SqmStatement sqmStatement,
Integer firstResult,
Integer maxResults,
Boolean cacheable,
String cacheRegion,
CacheMode cacheMode,
FlushMode flushMode,
Boolean readOnly,
LockOptions lockOptions,
Integer timeout,
Integer fetchSize,
String comment,
Map<String, String> parameterTypes,
Map<String, Object> hints) {
super( name, cacheable, cacheRegion, cacheMode, flushMode, readOnly, timeout, fetchSize, comment, hints );
this.sqmStatement = sqmStatement;
this.firstResult = firstResult;
this.maxResults = maxResults;
this.lockOptions = lockOptions;
this.parameterTypes = parameterTypes;
}
@Override
public void validate(QueryEngine queryEngine) {
}
@Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType) {
return new QuerySqmImpl<>( this, resultType, session );
}
@Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session) {
return toQuery(session, null);
}
@Override
public <T> SqmSelectionQuery<T> toSelectionQuery(Class<T> resultType, SharedSessionContractImplementor session) {
return new SqmSelectionQueryImpl<>(
this,
resultType,
session
);
}
@Override
public String getHqlString() {
return QuerySqmImpl.CRITERIA_HQL_STRING;
}
@Override
public SqmStatement getSqmStatement() {
return sqmStatement;
}
@Override
public Integer getFirstResult() {
return firstResult;
}
@Override
public Integer getMaxResults() {
return maxResults;
}
@Override
public LockOptions getLockOptions() {
return lockOptions;
}
@Override
public Map<String, String> getParameterTypes() {
return parameterTypes;
}
@Override
public NamedSqmQueryMemento makeCopy(String name) {
return new NamedCriteriaQueryMementoImpl(
name,
sqmStatement,
firstResult,
maxResults,
getCacheable(),
getCacheRegion(),
getCacheMode(),
getFlushMode(),
getReadOnly(),
lockOptions,
getTimeout(),
getFetchSize(),
getComment(),
parameterTypes,
getHints()
);
}
}

View File

@ -13,11 +13,14 @@ import org.hibernate.CacheMode;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.hql.spi.SqmQueryImplementor; import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.AbstractNamedQueryMemento; import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.internal.QuerySqmImpl; import org.hibernate.query.sqm.internal.QuerySqmImpl;
import org.hibernate.query.sqm.internal.SqmSelectionQueryImpl;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -30,7 +33,7 @@ import org.jboss.logging.Logger;
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implements NamedHqlQueryMemento, Serializable { public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implements NamedSqmQueryMemento, Serializable {
private static final Logger log = Logger.getLogger( NamedHqlQueryMementoImpl.class ); private static final Logger log = Logger.getLogger( NamedHqlQueryMementoImpl.class );
private final String hqlString; private final String hqlString;
@ -102,7 +105,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
} }
@Override @Override
public NamedHqlQueryMemento makeCopy(String name) { public NamedSqmQueryMemento makeCopy(String name) {
return new NamedHqlQueryMementoImpl( return new NamedHqlQueryMementoImpl(
name, name,
hqlString, hqlString,
@ -124,7 +127,7 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
@Override @Override
public void validate(QueryEngine queryEngine) { public void validate(QueryEngine queryEngine) {
queryEngine.getHqlTranslator().translate( getHqlString() ); queryEngine.getHqlTranslator().translate( hqlString );
} }
@Override @Override
@ -132,6 +135,20 @@ public class NamedHqlQueryMementoImpl extends AbstractNamedQueryMemento implemen
return toQuery( session, null ); return toQuery( session, null );
} }
@Override
public <T> SqmSelectionQuery<T> toSelectionQuery(Class<T> resultType, SharedSessionContractImplementor session) {
return new SqmSelectionQueryImpl<>(
this,
resultType,
session
);
}
@Override
public SqmStatement getSqmStatement() {
return null;
}
@Override @Override
public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType) { public <T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType) {
return new QuerySqmImpl<>( this, resultType, session ); return new QuerySqmImpl<>( this, resultType, session );

View File

@ -14,6 +14,6 @@
* *
* @see org.hibernate.query.hql.HqlTranslator * @see org.hibernate.query.hql.HqlTranslator
* @see org.hibernate.query.hql.spi.SqmQueryImplementor * @see org.hibernate.query.hql.spi.SqmQueryImplementor
* @see org.hibernate.query.hql.spi.NamedHqlQueryMemento * @see org.hibernate.query.sqm.spi.NamedSqmQueryMemento
*/ */
package org.hibernate.query.hql; package org.hibernate.query.hql;

View File

@ -1,128 +0,0 @@
/*
* 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.hql.spi;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.LockOptions;
import org.hibernate.boot.query.NamedHqlQueryDefinition;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.named.AbstractNamedQueryMemento;
import org.hibernate.query.named.NameableQuery;
import org.hibernate.query.named.NamedQueryMemento;
/**
* NamedQueryMemento for HQL queries
*
* @author Steve Ebersole
*/
public interface NamedHqlQueryMemento extends NamedQueryMemento {
/**
* Informational access to the HQL query string
*/
String getHqlString();
/**
* Convert the memento into a typed executable query
*/
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
/**
* Convert the memento into an untyped executable query
*/
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session);
Integer getFirstResult();
Integer getMaxResults();
LockOptions getLockOptions();
Map<String, String> getParameterTypes();
@Override
NamedHqlQueryMemento makeCopy(String name);
/**
* Delegate used in creating named HQL query mementos.
*
* @see NamedHqlQueryDefinition
* @see NameableQuery#toMemento
*/
class Builder extends AbstractNamedQueryMemento.AbstractBuilder<Builder> {
protected String hqlString;
protected LockOptions lockOptions;
protected Integer firstResult;
protected Integer maxResults;
protected Map<String,String> parameterTypes;
public Builder(String name) {
super( name );
}
@Override
protected Builder getThis() {
return this;
}
public Builder setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
return this;
}
public Builder addParameterType(String name, String typeName) {
if ( this.parameterTypes == null ) {
this.parameterTypes = new HashMap<>();
}
this.parameterTypes.put( name, typeName );
return this;
}
public Builder setParameterTypes(Map<String,String> parameterTypes) {
this.parameterTypes = parameterTypes;
return this;
}
public Builder setLockOptions(LockOptions lockOptions) {
this.lockOptions = lockOptions;
return this;
}
public Builder setFirstResult(Integer firstResult) {
this.firstResult = firstResult;
return this;
}
public Builder setMaxResults(Integer maxResults) {
this.maxResults = maxResults;
return this;
}
public NamedHqlQueryMemento createNamedQueryDefinition() {
return new NamedHqlQueryMementoImpl(
name,
hqlString,
firstResult,
maxResults,
cacheable,
cacheRegion,
cacheMode,
flushMode,
readOnly,
lockOptions,
timeout,
fetchSize,
comment,
parameterTypes,
hints
);
}
}
}

View File

@ -23,6 +23,7 @@ import org.hibernate.query.QueryParameter;
import org.hibernate.query.ResultListTransformer; import org.hibernate.query.ResultListTransformer;
import org.hibernate.query.TupleTransformer; import org.hibernate.query.TupleTransformer;
import org.hibernate.query.named.NameableQuery; import org.hibernate.query.named.NameableQuery;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.spi.ParameterMetadataImplementor; import org.hibernate.query.spi.ParameterMetadataImplementor;
import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.spi.SqmQuery; import org.hibernate.query.spi.SqmQuery;
@ -41,7 +42,7 @@ import jakarta.persistence.TemporalType;
*/ */
public interface SqmQueryImplementor<R> extends QueryImplementor<R>, SqmQuery, NameableQuery { public interface SqmQueryImplementor<R> extends QueryImplementor<R>, SqmQuery, NameableQuery {
@Override @Override
NamedHqlQueryMemento toMemento(String name); NamedQueryMemento toMemento(String name);
@Override @Override
ParameterMetadataImplementor getParameterMetadata(); ParameterMetadataImplementor getParameterMetadata();

View File

@ -19,13 +19,13 @@ import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.procedure.spi.NamedCallableQueryMemento;
import org.hibernate.query.hql.HqlTranslator; import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.named.NamedObjectRepository; import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.named.NamedResultSetMappingMemento; import org.hibernate.query.named.NamedResultSetMappingMemento;
import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.spi.QueryInterpretationCache;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -35,17 +35,17 @@ import org.jboss.logging.Logger;
public class NamedObjectRepositoryImpl implements NamedObjectRepository { public class NamedObjectRepositoryImpl implements NamedObjectRepository {
private static final Logger log = Logger.getLogger( NamedObjectRepository.class ); private static final Logger log = Logger.getLogger( NamedObjectRepository.class );
private final Map<String, NamedHqlQueryMemento> hqlMementoMap; private final Map<String, NamedSqmQueryMemento> sqmMementoMap;
private final Map<String, NamedNativeQueryMemento> sqlMementoMap; private final Map<String, NamedNativeQueryMemento> sqlMementoMap;
private final Map<String, NamedCallableQueryMemento> callableMementoMap; private final Map<String, NamedCallableQueryMemento> callableMementoMap;
private final Map<String, NamedResultSetMappingMemento> resultSetMappingMementoMap; private final Map<String, NamedResultSetMappingMemento> resultSetMappingMementoMap;
public NamedObjectRepositoryImpl( public NamedObjectRepositoryImpl(
Map<String,NamedHqlQueryMemento> hqlMementoMap, Map<String,NamedSqmQueryMemento> sqmMementoMap,
Map<String,NamedNativeQueryMemento> sqlMementoMap, Map<String,NamedNativeQueryMemento> sqlMementoMap,
Map<String,NamedCallableQueryMemento> callableMementoMap, Map<String,NamedCallableQueryMemento> callableMementoMap,
Map<String,NamedResultSetMappingMemento> resultSetMappingMementoMap) { Map<String,NamedResultSetMappingMemento> resultSetMappingMementoMap) {
this.hqlMementoMap = hqlMementoMap; this.sqmMementoMap = sqmMementoMap;
this.sqlMementoMap = sqlMementoMap; this.sqlMementoMap = sqlMementoMap;
this.callableMementoMap = callableMementoMap; this.callableMementoMap = callableMementoMap;
this.resultSetMappingMementoMap = resultSetMappingMementoMap; this.resultSetMappingMementoMap = resultSetMappingMementoMap;
@ -53,25 +53,24 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// HQL mementos // Named SQM Memento
@Override @Override
public NamedHqlQueryMemento getHqlQueryMemento(String queryName) { public NamedSqmQueryMemento getSqmQueryMemento(String queryName) {
return hqlMementoMap.get( queryName ); return sqmMementoMap.get( queryName );
} }
@Override @Override
public void visitHqlQueryMementos(Consumer<NamedHqlQueryMemento> action) { public void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento> action) {
hqlMementoMap.values().forEach( action ); sqmMementoMap.values().forEach( action );
} }
@Override @Override
public synchronized void registerHqlQueryMemento(String name, NamedHqlQueryMemento descriptor) { public void registerSqmQueryMemento(String name, NamedSqmQueryMemento descriptor) {
hqlMementoMap.put( name, descriptor ); sqmMementoMap.put( name, descriptor );
sqlMementoMap.remove( name ); sqlMementoMap.remove( name );
} }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// SQL mementos // SQL mementos
@ -88,7 +87,7 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
@Override @Override
public synchronized void registerNativeQueryMemento(String name, NamedNativeQueryMemento descriptor) { public synchronized void registerNativeQueryMemento(String name, NamedNativeQueryMemento descriptor) {
sqlMementoMap.put( name, descriptor ); sqlMementoMap.put( name, descriptor );
hqlMementoMap.remove( name ); sqmMementoMap.remove( name );
} }
@ -138,11 +137,11 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
MetadataImplementor bootMetamodel, MetadataImplementor bootMetamodel,
String registrationName) { String registrationName) {
NamedQueryMemento namedQuery = hqlMementoMap.get( registrationName ); NamedQueryMemento namedQuery = sqlMementoMap.get( registrationName );
if ( namedQuery != null ) { if ( namedQuery != null ) {
return namedQuery; return namedQuery;
} }
namedQuery = sqlMementoMap.get( registrationName ); namedQuery = sqmMementoMap.get( registrationName );
if ( namedQuery != null ) { if ( namedQuery != null ) {
return namedQuery; return namedQuery;
} }
@ -152,8 +151,8 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
} }
final NamedHqlQueryDefinition namedHqlQueryDefinition = bootMetamodel.getNamedHqlQueryMapping( registrationName ); final NamedHqlQueryDefinition namedHqlQueryDefinition = bootMetamodel.getNamedHqlQueryMapping( registrationName );
if ( namedHqlQueryDefinition != null ) { if ( namedHqlQueryDefinition != null ) {
final NamedHqlQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory ); final NamedSqmQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory );
hqlMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved ); sqmMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved );
return resolved; return resolved;
} }
final NamedNativeQueryDefinition namedNativeQueryDefinition = bootMetamodel.getNamedNativeQueryMapping( registrationName ); final NamedNativeQueryDefinition namedNativeQueryDefinition = bootMetamodel.getNamedNativeQueryMapping( registrationName );
@ -178,8 +177,8 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
BootstrapContext bootstrapContext) { BootstrapContext bootstrapContext) {
bootMetamodel.visitNamedHqlQueryDefinitions( bootMetamodel.visitNamedHqlQueryDefinitions(
namedHqlQueryDefinition -> { namedHqlQueryDefinition -> {
final NamedHqlQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory ); final NamedSqmQueryMemento resolved = namedHqlQueryDefinition.resolve( sessionFactory );
hqlMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved ); sqmMementoMap.put( namedHqlQueryDefinition.getRegistrationName(), resolved );
} }
); );
@ -218,8 +217,8 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
final boolean cachingEnabled = interpretationCache.isEnabled(); final boolean cachingEnabled = interpretationCache.isEnabled();
// Check named HQL queries // Check named HQL queries
log.debugf( "Checking %s named HQL queries", hqlMementoMap.size() ); log.debugf( "Checking %s named HQL queries", sqmMementoMap.size() );
for ( NamedHqlQueryMemento hqlMemento : hqlMementoMap.values() ) { for ( NamedSqmQueryMemento hqlMemento : sqmMementoMap.values() ) {
try { try {
log.debugf( "Checking named HQL query: %s", hqlMemento.getRegistrationName() ); log.debugf( "Checking named HQL query: %s", hqlMemento.getRegistrationName() );
String queryString = hqlMemento.getHqlString(); String queryString = hqlMemento.getHqlString();
@ -277,7 +276,7 @@ public class NamedObjectRepositoryImpl implements NamedObjectRepository {
@Override @Override
public void close() { public void close() {
hqlMementoMap.clear(); sqmMementoMap.clear();
sqlMementoMap.clear(); sqlMementoMap.clear();
callableMementoMap.clear(); callableMementoMap.clear();
resultSetMappingMementoMap.clear(); resultSetMappingMementoMap.clear();

View File

@ -15,9 +15,9 @@ import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.procedure.spi.NamedCallableQueryMemento;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.spi.QueryEngine; import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
/** /**
* Repository for references to named things related with queries. This includes * Repository for references to named things related with queries. This includes
@ -30,11 +30,11 @@ import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
public interface NamedObjectRepository { public interface NamedObjectRepository {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Named HQL Memento // Named SQM Memento
NamedHqlQueryMemento getHqlQueryMemento(String queryName); NamedSqmQueryMemento getSqmQueryMemento(String queryName);
void visitHqlQueryMementos(Consumer<NamedHqlQueryMemento> action); void visitSqmQueryMementos(Consumer<NamedSqmQueryMemento> action);
void registerHqlQueryMemento(String name, NamedHqlQueryMemento descriptor); void registerSqmQueryMemento(String name, NamedSqmQueryMemento descriptor);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -48,11 +48,11 @@ import org.hibernate.query.QueryParameter;
import org.hibernate.query.QueryTypeMismatchException; import org.hibernate.query.QueryTypeMismatchException;
import org.hibernate.query.SelectionQuery; import org.hibernate.query.SelectionQuery;
import org.hibernate.query.criteria.JpaSelection; import org.hibernate.query.criteria.JpaSelection;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.internal.ScrollableResultsIterator; import org.hibernate.query.internal.ScrollableResultsIterator;
import org.hibernate.query.named.NamedQueryMemento; import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.from.SqmRoot; import org.hibernate.query.sqm.tree.from.SqmRoot;
@ -127,7 +127,7 @@ public abstract class AbstractSelectionQuery<R>
return null; return null;
} }
protected void applyOptions(NamedHqlQueryMemento memento) { protected void applyOptions(NamedSqmQueryMemento memento) {
applyOptions( (NamedQueryMemento) memento ); applyOptions( (NamedQueryMemento) memento );
if ( memento.getFirstResult() != null ) { if ( memento.getFirstResult() != null ) {

View File

@ -7,7 +7,6 @@
package org.hibernate.query.sqm.internal; package org.hibernate.query.sqm.internal;
import java.io.Serializable; import java.io.Serializable;
import java.sql.Types;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -16,7 +15,6 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -26,7 +24,6 @@ import jakarta.persistence.LockModeType;
import jakarta.persistence.Parameter; import jakarta.persistence.Parameter;
import jakarta.persistence.PersistenceException; import jakarta.persistence.PersistenceException;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import jakarta.persistence.Tuple;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
@ -47,8 +44,6 @@ import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.collections.IdentitySet; import org.hibernate.internal.util.collections.IdentitySet;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.BindableType; import org.hibernate.query.BindableType;
@ -57,17 +52,17 @@ import org.hibernate.query.ImmutableEntityUpdateQueryHandlingMode;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.query.QueryLogging; import org.hibernate.query.QueryLogging;
import org.hibernate.query.QueryParameter; import org.hibernate.query.QueryParameter;
import org.hibernate.query.QueryTypeMismatchException;
import org.hibernate.query.ResultListTransformer; import org.hibernate.query.ResultListTransformer;
import org.hibernate.query.SemanticException; import org.hibernate.query.SemanticException;
import org.hibernate.query.TupleTransformer; import org.hibernate.query.TupleTransformer;
import org.hibernate.query.criteria.internal.NamedCriteriaQueryMementoImpl;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl; import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.hql.internal.QuerySplitter; import org.hibernate.query.hql.internal.QuerySplitter;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.hql.spi.SqmQueryImplementor; import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext; import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext;
import org.hibernate.query.internal.ParameterMetadataImpl; import org.hibernate.query.internal.ParameterMetadataImpl;
import org.hibernate.query.internal.QueryParameterBindingsImpl; import org.hibernate.query.internal.QueryParameterBindingsImpl;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.spi.AbstractSelectionQuery; import org.hibernate.query.spi.AbstractSelectionQuery;
import org.hibernate.query.spi.DomainQueryExecutionContext; import org.hibernate.query.spi.DomainQueryExecutionContext;
import org.hibernate.query.spi.HqlInterpretation; import org.hibernate.query.spi.HqlInterpretation;
@ -80,8 +75,6 @@ import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.spi.ScrollableResultsImplementor; import org.hibernate.query.spi.ScrollableResultsImplementor;
import org.hibernate.query.spi.SelectQueryPlan; import org.hibernate.query.spi.SelectQueryPlan;
import org.hibernate.query.sqm.SqmExpressible;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.internal.SqmInterpretationsKey.InterpretationsKeySource; import org.hibernate.query.sqm.internal.SqmInterpretationsKey.InterpretationsKeySource;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
@ -93,19 +86,15 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter; import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper; import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement; import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement; import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement; import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement;
import org.hibernate.query.sqm.tree.insert.SqmValues; import org.hibernate.query.sqm.tree.insert.SqmValues;
import org.hibernate.query.sqm.tree.select.SqmQueryGroup;
import org.hibernate.query.sqm.tree.select.SqmQueryPart; import org.hibernate.query.sqm.tree.select.SqmQueryPart;
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelection; import org.hibernate.query.sqm.tree.select.SqmSelection;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.sql.results.internal.TupleMetadata; import org.hibernate.sql.results.internal.TupleMetadata;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE; import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE;
import static org.hibernate.jpa.HibernateHints.HINT_CACHE_MODE; import static org.hibernate.jpa.HibernateHints.HINT_CACHE_MODE;
@ -150,7 +139,7 @@ public class QuerySqmImpl<R>
* Creates a Query instance from a named HQL memento * Creates a Query instance from a named HQL memento
*/ */
public QuerySqmImpl( public QuerySqmImpl(
NamedHqlQueryMemento memento, NamedHqlQueryMementoImpl memento,
Class<R> resultType, Class<R> resultType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
super( session ); super( session );
@ -176,10 +165,20 @@ public class QuerySqmImpl<R>
validateStatement( sqm, resultType ); validateStatement( sqm, resultType );
setComment( hql ); setComment( hql );
applyOptions( memento ); applyOptions( memento );
this.tupleMetadata = buildTupleMetadata( sqm, resultType ); this.tupleMetadata = buildTupleMetadata( sqm, resultType );
} }
public QuerySqmImpl(
NamedCriteriaQueryMementoImpl memento,
Class<R> resultType,
SharedSessionContractImplementor session) {
this( memento.getSqmStatement(), resultType, session );
applyOptions( memento );
}
/** /**
* Form used for HQL queries * Form used for HQL queries
*/ */
@ -1008,9 +1007,33 @@ public class QuerySqmImpl<R>
// Named query externalization // Named query externalization
@Override @Override
public NamedHqlQueryMemento toMemento(String name) { public NamedQueryMemento toMemento(String name) {
if ( CRITERIA_HQL_STRING.equals( getQueryString() ) ) { if ( CRITERIA_HQL_STRING.equals( getQueryString() ) ) {
throw new UnsupportedOperationException( "Criteria-based Query cannot be saved as a named query" ); final SqmStatement sqmStatement ;
if ( !getSession().isJpaCriteriaCopyComplianceEnabled() ) {
sqmStatement = getSqmStatement().copy( SqmCopyContext.simpleContext() );
}
else {
// the statement has already been copied
sqmStatement = getSqmStatement();
}
return new NamedCriteriaQueryMementoImpl(
name,
sqmStatement,
getFirstResult(),
getMaxResults(),
isCacheable(),
getCacheRegion(),
getCacheMode(),
getHibernateFlushMode(),
isReadOnly(),
getLockOptions(),
getTimeout(),
getFetchSize(),
getComment(),
Collections.emptyMap(),
getHints()
);
} }
return new NamedHqlQueryMementoImpl( return new NamedHqlQueryMementoImpl(

View File

@ -12,7 +12,6 @@ import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
import jakarta.persistence.FlushModeType; import jakarta.persistence.FlushModeType;
@ -34,12 +33,11 @@ import org.hibernate.internal.util.collections.IdentitySet;
import org.hibernate.jpa.internal.util.FlushModeTypeHelper; import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.jpa.internal.util.LockModeTypeHelper; import org.hibernate.jpa.internal.util.LockModeTypeHelper;
import org.hibernate.query.BindableType; import org.hibernate.query.BindableType;
import org.hibernate.query.IllegalSelectQueryException;
import org.hibernate.query.QueryLogging; import org.hibernate.query.QueryLogging;
import org.hibernate.query.QueryParameter; import org.hibernate.query.QueryParameter;
import org.hibernate.query.QueryTypeMismatchException; import org.hibernate.query.criteria.internal.NamedCriteriaQueryMementoImpl;
import org.hibernate.query.hql.internal.NamedHqlQueryMementoImpl;
import org.hibernate.query.hql.internal.QuerySplitter; import org.hibernate.query.hql.internal.QuerySplitter;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext; import org.hibernate.query.internal.DelegatingDomainQueryExecutionContext;
import org.hibernate.query.internal.ParameterMetadataImpl; import org.hibernate.query.internal.ParameterMetadataImpl;
import org.hibernate.query.internal.QueryParameterBindingsImpl; import org.hibernate.query.internal.QueryParameterBindingsImpl;
@ -56,6 +54,7 @@ import org.hibernate.query.spi.ScrollableResultsImplementor;
import org.hibernate.query.spi.SelectQueryPlan; import org.hibernate.query.spi.SelectQueryPlan;
import org.hibernate.query.sqm.SqmSelectionQuery; import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.internal.SqmInterpretationsKey.InterpretationsKeySource; import org.hibernate.query.sqm.internal.SqmInterpretationsKey.InterpretationsKeySource;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmCopyContext;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter; import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper; import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
@ -114,7 +113,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
} }
public SqmSelectionQueryImpl( public SqmSelectionQueryImpl(
NamedHqlQueryMemento memento, NamedHqlQueryMementoImpl memento,
Class<R> resultType, Class<R> resultType,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {
super( session ); super( session );
@ -145,6 +144,14 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
this.tupleMetadata = buildTupleMetadata( sqm, resultType ); this.tupleMetadata = buildTupleMetadata( sqm, resultType );
} }
public SqmSelectionQueryImpl(
NamedCriteriaQueryMementoImpl memento,
Class<R> resultType,
SharedSessionContractImplementor session) {
this( (SqmSelectStatement<R>) memento.getSqmStatement(), session);
applyOptions( memento );
}
public SqmSelectionQueryImpl( public SqmSelectionQueryImpl(
SqmSelectStatement<R> criteria, SqmSelectStatement<R> criteria,
SharedSessionContractImplementor session) { SharedSessionContractImplementor session) {

View File

@ -0,0 +1,44 @@
/*
* 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.sqm.spi;
import java.util.Map;
import org.hibernate.LockOptions;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.hql.spi.SqmQueryImplementor;
import org.hibernate.query.named.NamedQueryMemento;
import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.tree.SqmStatement;
public interface NamedSqmQueryMemento extends NamedQueryMemento {
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
/**
* Convert the memento into an untyped executable query
*/
<T> SqmQueryImplementor<T> toQuery(SharedSessionContractImplementor session);
<T> SqmSelectionQuery<T> toSelectionQuery(Class<T> resultType, SharedSessionContractImplementor session);
String getHqlString();
SqmStatement getSqmStatement();
Integer getFirstResult();
Integer getMaxResults();
LockOptions getLockOptions();
Map<String, String> getParameterTypes();
@Override
NamedSqmQueryMemento makeCopy(String name);
}

View File

@ -0,0 +1,88 @@
/*
* 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.orm.test.jpa.compliance;
import java.util.List;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import static org.junit.jupiter.api.Assertions.assertEquals;
@Jpa(
annotatedClasses = NamedQueryTest.Person.class
)
public class NamedQueryTest {
@BeforeEach
public void setup(EntityManagerFactoryScope scope) {
scope.inTransaction(
entityManager -> {
Person person1 = new Person( 1, "Andrea" );
Person person2 = new Person( 2, "Alberto" );
entityManager.persist( person1 );
entityManager.persist( person2 );
}
);
}
@Test
public void testNameQueryCreationFromCritera(EntityManagerFactoryScope scope) {
final EntityManagerFactory entityManagerFactory = scope.getEntityManagerFactory();
scope.inEntityManager(
entityManager -> {
final CriteriaBuilder criteriaBuilder = entityManagerFactory.getCriteriaBuilder();
final CriteriaQuery<Integer> query = criteriaBuilder.createQuery( Integer.class );
final Root<Person> person = query.from( Person.class );
query.select( person.get( "id" ) );
query.where( criteriaBuilder.equal( person.get( "name" ), "Alberto" ) );
entityManagerFactory.addNamedQuery( "criteria_query", entityManager.createQuery( query ) );
List<Integer> ids = entityManager.createNamedQuery( "criteria_query", Integer.class )
.getResultList();
assertEquals( 1, ids.size() );
assertEquals( 2, ids.get( 0 ) );
}
);
}
@Entity(name = "Person")
@Table(name = "PERSON_TABLE")
public static class Person {
@Id
private Integer id;
private String name;
public Person() {
}
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
}
}

View File

@ -13,7 +13,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.orm.test.jpa.Distributor; import org.hibernate.orm.test.jpa.Distributor;
import org.hibernate.orm.test.jpa.Item; import org.hibernate.orm.test.jpa.Item;
import org.hibernate.orm.test.jpa.Wallet; import org.hibernate.orm.test.jpa.Wallet;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa; import org.hibernate.testing.orm.junit.Jpa;
@ -108,9 +108,9 @@ public class AddNamedQueryTest {
// first, lets check the underlying stored query def // first, lets check the underlying stored query def
SessionFactoryImplementor sfi = scope.getEntityManagerFactory() SessionFactoryImplementor sfi = scope.getEntityManagerFactory()
.unwrap( SessionFactoryImplementor.class ); .unwrap( SessionFactoryImplementor.class );
NamedHqlQueryMemento def = sfi.getQueryEngine() NamedSqmQueryMemento def = sfi.getQueryEngine()
.getNamedObjectRepository() .getNamedObjectRepository()
.getHqlQueryMemento( name ); .getSqmQueryMemento( name );
assertEquals( LockMode.OPTIMISTIC, def.getLockOptions().getLockMode() ); assertEquals( LockMode.OPTIMISTIC, def.getLockOptions().getLockMode() );
// then lets create a query by name and check its setting // then lets create a query by name and check its setting
@ -139,9 +139,9 @@ public class AddNamedQueryTest {
// first, lets check the underlying stored query def // first, lets check the underlying stored query def
SessionFactoryImplementor sfi = scope.getEntityManagerFactory() SessionFactoryImplementor sfi = scope.getEntityManagerFactory()
.unwrap( SessionFactoryImplementor.class ); .unwrap( SessionFactoryImplementor.class );
NamedHqlQueryMemento def = sfi.getQueryEngine() NamedSqmQueryMemento def = sfi.getQueryEngine()
.getNamedObjectRepository() .getNamedObjectRepository()
.getHqlQueryMemento( name ); .getSqmQueryMemento( name );
assertEquals( FlushMode.COMMIT, def.getFlushMode() ); assertEquals( FlushMode.COMMIT, def.getFlushMode() );
// then lets create a query by name and check its setting // then lets create a query by name and check its setting

View File

@ -10,9 +10,9 @@ import jakarta.persistence.FlushModeType;
import org.hibernate.CacheMode; import org.hibernate.CacheMode;
import org.hibernate.query.Query; import org.hibernate.query.Query;
import org.hibernate.query.hql.spi.NamedHqlQueryMemento;
import org.hibernate.query.named.NamedObjectRepository; import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.spi.QueryImplementor; import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.query.sqm.spi.NamedSqmQueryMemento;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
@ -35,10 +35,10 @@ public class SimpleNamedQueryTests {
.getQueryEngine() .getQueryEngine()
.getNamedObjectRepository(); .getNamedObjectRepository();
final NamedHqlQueryMemento simpleMemento = namedObjectRepository.getHqlQueryMemento( "simple" ); final NamedSqmQueryMemento simpleMemento = namedObjectRepository.getSqmQueryMemento( "simple" );
assertThat( simpleMemento, notNullValue() ); assertThat( simpleMemento, notNullValue() );
final NamedHqlQueryMemento restrictedMemento = namedObjectRepository.getHqlQueryMemento( "restricted" ); final NamedSqmQueryMemento restrictedMemento = namedObjectRepository.getSqmQueryMemento( "restricted" );
assertThat( restrictedMemento, notNullValue() ); assertThat( restrictedMemento, notNullValue() );
} }
@ -54,10 +54,10 @@ public class SimpleNamedQueryTests {
.getQueryEngine() .getQueryEngine()
.getNamedObjectRepository(); .getNamedObjectRepository();
final NamedHqlQueryMemento simpleMemento = namedObjectRepository.getHqlQueryMemento( "simple" ); final NamedSqmQueryMemento simpleMemento = namedObjectRepository.getSqmQueryMemento( "simple" );
assertThat( simpleMemento, notNullValue() ); assertThat( simpleMemento, notNullValue() );
final NamedHqlQueryMemento restrictedMemento = namedObjectRepository.getHqlQueryMemento( "restricted" ); final NamedSqmQueryMemento restrictedMemento = namedObjectRepository.getSqmQueryMemento( "restricted" );
assertThat( restrictedMemento, notNullValue() ); assertThat( restrictedMemento, notNullValue() );
} }