HHH-15030 - SelectQuery, MutationQuery, etc

SelectQuery based on Criteria
SelectQuery based on named query (HQL only)
MutationQuery based on named query (HQL only)
This commit is contained in:
Steve Ebersole 2022-01-26 13:43:27 -06:00
parent 751aa6f50f
commit 131b7bb4e0
8 changed files with 409 additions and 123 deletions

View File

@ -490,13 +490,18 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
}
@Override
public SelectionQuery<?> createSelectQuery(String hqlString) {
return queryDelegate().createSelectQuery( hqlString );
public SelectionQuery<?> createSelectionQuery(String hqlString) {
return queryDelegate().createSelectionQuery( hqlString );
}
@Override
public <R> SelectionQuery<R> createSelectQuery(String hqlString, Class<R> resultType) {
return queryDelegate().createSelectQuery( hqlString, resultType );
public <R> SelectionQuery<R> createSelectionQuery(String hqlString, Class<R> resultType) {
return queryDelegate().createSelectionQuery( hqlString, resultType );
}
@Override
public <R> SelectionQuery<R> createSelectionQuery(CriteriaQuery<R> criteria) {
return queryDelegate().createSelectionQuery( criteria );
}
@Override
@ -514,6 +519,16 @@ public class SessionDelegatorBaseImpl implements SessionImplementor {
return queryDelegate().createNamedQuery( name, resultClass );
}
@Override
public SelectionQuery<?> createNamedSelectionQuery(String name) {
return delegate().createNamedSelectionQuery( name );
}
@Override
public <R> SelectionQuery<R> createNamedSelectionQuery(String name, Class<R> resultType) {
return delegate().createNamedSelectionQuery( name, resultType );
}
@Override @SuppressWarnings("rawtypes")
public NativeQueryImplementor createNativeQuery(String sqlString) {
return queryDelegate().createNativeQuery( sqlString );

View File

@ -15,6 +15,13 @@ import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;
import java.util.function.Function;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.NamedNativeQuery;
import jakarta.persistence.TransactionRequiredException;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
import org.hibernate.CacheMode;
import org.hibernate.EmptyInterceptor;
@ -88,13 +95,6 @@ import org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoo
import org.hibernate.resource.transaction.spi.TransactionCoordinator;
import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.TransactionRequiredException;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
import static java.lang.Boolean.TRUE;
/**
@ -653,7 +653,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
}
@Override
public SelectionQuery<?> createSelectQuery(String hqlString) {
public SelectionQuery<?> createSelectionQuery(String hqlString) {
checkOpen();
pulseTransactionCoordinator();
delayedAfterCompletion();
@ -666,8 +666,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
s -> queryEngine.getHqlTranslator().translate( hqlString )
);
if ( hqlInterpretation.getSqmStatement() instanceof SqmDmlStatement ) {
throw new IllegalSelectQueryException( "Expecting a selection query, but found `" + hqlString + "`" );
if ( !( hqlInterpretation.getSqmStatement() instanceof SqmSelectStatement ) ) {
throw new IllegalSelectQueryException( "Expecting a selection query, but found `" + hqlString + "`", hqlString );
}
final SqmSelectionQuery<?> query = new SqmSelectionQueryImpl<>( hqlString, hqlInterpretation, this );
@ -679,13 +679,13 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
}
catch (RuntimeException e) {
markForRollbackOnly();
throw getExceptionConverter().convert( e );
throw e;
}
}
@Override
public <R> SelectionQuery<R> createSelectQuery(String hqlString, Class<R> expectedResultType) {
final SelectionQuery<?> selectQuery = createSelectQuery( hqlString );
public <R> SelectionQuery<R> createSelectionQuery(String hqlString, Class<R> expectedResultType) {
final SelectionQuery<?> selectQuery = createSelectionQuery( hqlString );
//noinspection unchecked
final Class<?> resultType = ( (SqmSelectionQueryImpl<R>) selectQuery ).getResultType();
if ( resultType == null || expectedResultType.isAssignableFrom( resultType ) ) {
@ -703,6 +703,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
);
}
@Override
public <R> SelectionQuery<R> createSelectionQuery(CriteriaQuery<R> criteria) {
return new SqmSelectionQueryImpl<>( (SqmSelectStatement<R>) criteria, this );
}
@Override
public <T> QueryImplementor<T> createQuery(String queryString, Class<T> resultClass) {
@ -842,6 +846,75 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
return buildNamedQuery( name, resultClass );
}
@Override
public SelectionQuery<?> createNamedSelectionQuery(String queryName) {
return createNamedSelectionQuery( queryName, null );
}
@Override
public <R> SelectionQuery<R> createNamedSelectionQuery(String queryName, Class<R> expectedResultType) {
checkOpen();
pulseTransactionCoordinator();
delayedAfterCompletion();
// 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
final NamedHqlQueryMemento namedHqlDescriptor = getFactory().getQueryEngine()
.getNamedObjectRepository()
.getHqlQueryMemento( queryName );
if ( namedHqlDescriptor != null ) {
return createNamedHqlSelectionQuery( namedHqlDescriptor, expectedResultType );
}
// otherwise, see if it is a named native query
final NamedNativeQueryMemento namedNativeDescriptor = getFactory().getQueryEngine()
.getNamedObjectRepository()
.getNativeQueryMemento( queryName );
if ( namedNativeDescriptor != null ) {
return createNamedNativeSelectionQuery( namedNativeDescriptor, expectedResultType );
}
throw new UnknownNamedQueryException( queryName );
}
private <R> SelectionQuery<R> createNamedNativeSelectionQuery(
NamedNativeQueryMemento memento,
Class<R> expectedResultType) {
throw new UnsupportedOperationException(
String.format(
Locale.ROOT,
"Support for `@%s` + `%s` is not (yet) implemented",
NamedNativeQuery.class.getName(),
SelectionQuery.class.getName()
)
);
}
private <R> SqmSelectionQueryImpl<R> createNamedHqlSelectionQuery(
NamedHqlQueryMemento memento,
Class<R> expectedResultType) {
final SqmSelectionQueryImpl<R> selectionQuery = new SqmSelectionQueryImpl<>( memento, expectedResultType, this );
if ( StringHelper.isEmpty( memento.getComment() ) ) {
selectionQuery.setComment( "Named HQL query : " + memento.getRegistrationName() );
}
else {
selectionQuery.setComment( memento.getComment() );
}
applyQuerySettingsAndHints( selectionQuery );
if ( memento.getLockOptions() != null ) {
selectionQuery.getLockOptions().overlay( memento.getLockOptions() );
}
return selectionQuery;
}
@Override
public void doWork(final Work work) throws HibernateException {
WorkExecutorVisitable<Void> realWork = (workExecutor, connection) -> {

View File

@ -9,7 +9,7 @@ package org.hibernate.query;
import org.hibernate.QueryException;
/**
* Indicates an attempt to call {@link QueryProducer#createSelectQuery(String)}
* Indicates an attempt to call {@link QueryProducer#createSelectionQuery(String)}
* with a non-selection query (generally a mutation query)
*
* @author Steve Ebersole

View File

@ -39,7 +39,7 @@ public interface QueryProducer {
* @see jakarta.persistence.EntityManager#createQuery(String)
*
* @deprecated use {@link #createQuery(String, Class)},
* {@link #createSelectQuery} or {@link #createMutationQuery(String)}
* {@link #createSelectionQuery} or {@link #createMutationQuery(String)}
* depending on intention
*/
@Deprecated(since = "6.0") @SuppressWarnings("rawtypes")
@ -168,7 +168,7 @@ public interface QueryProducer {
* @throws IllegalSelectQueryException if the given HQL query
* is an insert, update or delete query
*/
SelectionQuery<?> createSelectQuery(String hqlString);
SelectionQuery<?> createSelectionQuery(String hqlString);
/**
* Create a {@link SelectionQuery} reference for the given HQL.
@ -180,7 +180,14 @@ public interface QueryProducer {
* @throws IllegalSelectQueryException if the given HQL query
* is an insert, update or delete query
*/
<R> SelectionQuery<R> createSelectQuery(String hqlString, Class<R> resultType);
<R> SelectionQuery<R> createSelectionQuery(String hqlString, Class<R> resultType);
/**
* Create a {@link SelectionQuery} reference for the given Criteria.
*
* @see jakarta.persistence.EntityManager#createQuery(CriteriaQuery)
*/
<R> SelectionQuery<R> createSelectionQuery(CriteriaQuery<R> criteria);
/**
* Create a MutationQuery reference for the given HQL insert,
@ -248,6 +255,25 @@ public interface QueryProducer {
*/
<R> Query<R> createNamedQuery(String name, Class<R> resultClass);
/**
* Create a {@link SelectionQuery} instance for the
* named {@link jakarta.persistence.NamedQuery}
*
* @throws IllegalSelectQueryException if the given HQL query is a select query
* @throws UnknownNamedQueryException if no query has been defined with the given name
*/
SelectionQuery<?> createNamedSelectionQuery(String name);
/**
* Create a {@link SelectionQuery} instance for the
* named {@link jakarta.persistence.NamedQuery} with the expected
* result-type
*
* @throws IllegalSelectQueryException if the given HQL query is a select query
* @throws UnknownNamedQueryException if no query has been defined with the given name
*/
<R> SelectionQuery<R> createNamedSelectionQuery(String name, Class<R> resultType);
/**
* Create a {@link MutationQuery} instance for the given named insert,
* update, or delete HQL query. The named query might be defined as

View File

@ -16,7 +16,6 @@ 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;
import org.hibernate.query.spi.QueryImplementor;
/**
* NamedQueryMemento for HQL queries

View File

@ -12,8 +12,13 @@ import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Supplier;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType;
import jakarta.persistence.Parameter;
import jakarta.persistence.TemporalType;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
@ -29,16 +34,21 @@ import org.hibernate.internal.util.collections.IdentitySet;
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
import org.hibernate.query.BindableType;
import org.hibernate.query.IllegalSelectQueryException;
import org.hibernate.query.QueryLogging;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.QueryTypeMismatchException;
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.ParameterMetadataImpl;
import org.hibernate.query.internal.QueryParameterBindingsImpl;
import org.hibernate.query.spi.AbstractSelectionQuery;
import org.hibernate.query.spi.DomainQueryExecutionContext;
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.QueryInterpretationCache;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings;
@ -46,30 +56,30 @@ import org.hibernate.query.spi.ScrollableResultsImplementor;
import org.hibernate.query.spi.SelectQueryPlan;
import org.hibernate.query.sqm.SqmSelectionQuery;
import org.hibernate.query.sqm.internal.SqmInterpretationsKey.InterpretationsKeySource;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import org.hibernate.query.sqm.tree.select.SqmSelection;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.LockModeType;
import jakarta.persistence.Parameter;
import jakarta.persistence.TemporalType;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_RETRIEVE_MODE;
import static org.hibernate.cfg.AvailableSettings.JAKARTA_SHARED_CACHE_STORE_MODE;
import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_RETRIEVE_MODE;
import static org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_STORE_MODE;
import static org.hibernate.jpa.QueryHints.HINT_CACHEABLE;
import static org.hibernate.jpa.QueryHints.HINT_CACHE_MODE;
import static org.hibernate.jpa.QueryHints.HINT_CACHE_REGION;
import static org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE;
import static org.hibernate.jpa.QueryHints.HINT_FOLLOW_ON_LOCKING;
import static org.hibernate.jpa.QueryHints.HINT_READONLY;
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_REGION;
import static org.hibernate.jpa.HibernateHints.HINT_FETCH_SIZE;
import static org.hibernate.jpa.HibernateHints.HINT_FOLLOW_ON_LOCKING;
import static org.hibernate.jpa.HibernateHints.HINT_READ_ONLY;
import static org.hibernate.jpa.LegacySpecHints.HINT_JAVAEE_CACHE_RETRIEVE_MODE;
import static org.hibernate.jpa.LegacySpecHints.HINT_JAVAEE_CACHE_STORE_MODE;
import static org.hibernate.jpa.SpecHints.HINT_SPEC_CACHE_RETRIEVE_MODE;
import static org.hibernate.jpa.SpecHints.HINT_SPEC_CACHE_STORE_MODE;
import static org.hibernate.query.spi.SqlOmittingQueryOptions.omitSqlQueryOptions;
/**
* @author Steve Ebersole
*/
public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implements SqmSelectionQuery<R>, InterpretationsKeySource {
public static final String CRITERIA_HQL_STRING = "<criteria>";
private final String hql;
private final SqmSelectStatement<?> sqm;
@ -97,6 +107,49 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
setComment( hql );
}
public SqmSelectionQueryImpl(
NamedHqlQueryMemento memento,
Class<R> resultType,
SharedSessionContractImplementor session) {
super( session );
this.hql = memento.getHqlString();
this.resultType = resultType;
final SessionFactoryImplementor factory = session.getFactory();
final QueryEngine queryEngine = factory.getQueryEngine();
final QueryInterpretationCache interpretationCache = queryEngine.getInterpretationCache();
final HqlInterpretation hqlInterpretation = interpretationCache.resolveHqlInterpretation(
hql,
(s) -> queryEngine.getHqlTranslator().translate( hql )
);
if ( !( hqlInterpretation.getSqmStatement() instanceof SqmSelectStatement ) ) {
throw new IllegalSelectQueryException( "Expecting a selection query, but found `" + hql + "`", hql );
}
this.sqm = (SqmSelectStatement<?>) hqlInterpretation.getSqmStatement();
this.parameterMetadata = hqlInterpretation.getParameterMetadata();
this.domainParameterXref = hqlInterpretation.getDomainParameterXref();
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
if ( resultType != null ) {
final Class<R> determinedResultType = determineResultType( sqm );
if ( !resultType.isAssignableFrom( determinedResultType ) ) {
throw new QueryTypeMismatchException(
String.format(
Locale.ROOT,
"SelectionQuery result-type error - expecting `%s`, but found `%s`",
resultType.getName(),
determinedResultType.getName()
)
);
}
}
}
private static <T> Class<T> determineResultType(SqmSelectStatement<?> sqm) {
final List<SqmSelection<?>> selections = sqm.getQuerySpec().getSelectClause().getSelections();
if ( selections.size() == 1 ) {
@ -109,6 +162,42 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
return (Class<T>) Object[].class;
}
public SqmSelectionQueryImpl(
SqmSelectStatement<R> sqm,
SharedSessionContractImplementor session) {
super( session );
this.hql = CRITERIA_HQL_STRING;
this.sqm = sqm;
this.domainParameterXref = DomainParameterXref.from( sqm );
if ( ! domainParameterXref.hasParameters() ) {
this.parameterMetadata = ParameterMetadataImpl.EMPTY;
}
else {
this.parameterMetadata = new ParameterMetadataImpl( domainParameterXref.getQueryParameters() );
}
this.parameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, session.getFactory() );
// Parameters might be created through HibernateCriteriaBuilder.value which we need to bind here
for ( SqmParameter<?> sqmParameter : this.domainParameterXref.getParameterResolutions().getSqmParameters() ) {
if ( sqmParameter instanceof SqmJpaCriteriaParameterWrapper<?> ) {
final JpaCriteriaParameter<Object> jpaCriteriaParameter = ( (SqmJpaCriteriaParameterWrapper<Object>) sqmParameter ).getJpaCriteriaParameter();
final Object value = jpaCriteriaParameter.getValue();
// We don't set a null value, unless the type is also null which is the case when using HibernateCriteriaBuilder.value
if ( value != null || jpaCriteriaParameter.getNodeType() == null ) {
// Use the anticipated type for binding the value if possible
getQueryParameterBindings().getBinding( jpaCriteriaParameter )
.setBindValue( value, jpaCriteriaParameter.getAnticipatedType() );
}
}
}
this.resultType = determineResultType( sqm );
setComment( hql );
}
@SuppressWarnings("rawtypes")
public SqmSelectStatement getSqmStatement() {
return sqm;
@ -441,7 +530,7 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
super.collectHints( hints );
if ( isReadOnly() ) {
hints.put( HINT_READONLY, true );
hints.put( HINT_READ_ONLY, true );
}
putIfNotNull( hints, HINT_FETCH_SIZE, getFetchSize() );
@ -451,12 +540,10 @@ public class SqmSelectionQueryImpl<R> extends AbstractSelectionQuery<R> implemen
putIfNotNull( hints, HINT_CACHE_REGION, getCacheRegion() );
putIfNotNull( hints, HINT_CACHE_MODE, getCacheMode() );
putIfNotNull( hints, JAKARTA_SHARED_CACHE_RETRIEVE_MODE, getQueryOptions().getCacheRetrieveMode() );
putIfNotNull( hints, JAKARTA_SHARED_CACHE_STORE_MODE, getQueryOptions().getCacheStoreMode() );
//noinspection deprecation
putIfNotNull( hints, JPA_SHARED_CACHE_RETRIEVE_MODE, getQueryOptions().getCacheRetrieveMode() );
//noinspection deprecation
putIfNotNull( hints, JPA_SHARED_CACHE_STORE_MODE, getQueryOptions().getCacheStoreMode() );
putIfNotNull( hints, HINT_SPEC_CACHE_RETRIEVE_MODE, getQueryOptions().getCacheRetrieveMode() );
putIfNotNull( hints, HINT_SPEC_CACHE_STORE_MODE, getQueryOptions().getCacheStoreMode() );
putIfNotNull( hints, HINT_JAVAEE_CACHE_RETRIEVE_MODE, getQueryOptions().getCacheRetrieveMode() );
putIfNotNull( hints, HINT_JAVAEE_CACHE_STORE_MODE, getQueryOptions().getCacheStoreMode() );
}
final AppliedGraph appliedGraph = getQueryOptions().getAppliedGraph();

View File

@ -0,0 +1,165 @@
/*
* 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.query.sqm;
import jakarta.persistence.Basic;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;
import org.hibernate.ScrollMode;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.query.IllegalSelectQueryException;
import org.hibernate.query.SelectionQuery;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.domain.contacts.Contact;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@DomainModel(
standardModels = StandardDomainModel.CONTACTS,
annotatedClasses = BasicSelectionQueryTests.DummyEntity.class
)
@SessionFactory
public class BasicSelectionQueryTests {
@Test
public void typedEntitySelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final SelectionQuery<Contact> query = session.createSelectionQuery( "select c from Contact c", Contact.class );
checkResults( query, session );
} );
}
@Test
public void rawEntitySelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
// its unbounded
final SelectionQuery<?> query = session.createSelectionQuery( "select c from Contact c" );
checkResults( query, session );
} );
}
@Test
public void typedScalarSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final SelectionQuery<Contact.Name> nameQuery = session.createSelectionQuery( "select c.name from Contact c", Contact.Name.class );
checkResults( nameQuery, session );
final SelectionQuery<String> firstNameQuery = session.createSelectionQuery( "select c.name.first from Contact c", String.class );
checkResults( firstNameQuery, session );
} );
}
@Test
public void rawScalarSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final SelectionQuery<?> nameQuery = session.createSelectionQuery( "select c.name from Contact c" );
checkResults( nameQuery, session );
final SelectionQuery<?> firstNameQuery = session.createSelectionQuery( "select c.name.first from Contact c" );
checkResults( firstNameQuery, session );
} );
}
@Test
public void typesNamedSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final SelectionQuery<Contact.Name> nameQuery = session.createNamedSelectionQuery( "hql-name", Contact.Name.class );
checkResults( nameQuery, session );
final SelectionQuery<String> firstNameQuery = session.createNamedSelectionQuery( "hql-first-name", String.class );
checkResults( firstNameQuery, session );
} );
}
@Test
public void rawNamedSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final SelectionQuery<?> nameQuery = session.createNamedSelectionQuery( "hql-name" );
checkResults( nameQuery, session );
final SelectionQuery<?> firstNameQuery = session.createNamedSelectionQuery( "hql-first-name" );
checkResults( firstNameQuery, session );
} );
}
@Test
public void mutationAsSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
try {
session.createSelectionQuery( "delete from Contact" );
fail( "Expecting IllegalSelectQueryException" );
}
catch (IllegalSelectQueryException expected) {
}
} );
}
@Test
public void namedMutationAsSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
try {
session.createNamedSelectionQuery( "hql-mutation" );
fail( "Expecting IllegalSelectQueryException" );
}
catch (IllegalSelectQueryException expected) {
}
} );
}
private void checkResults(SelectionQuery<?> query, SessionImplementor session) {
query.list();
query.getResultList();
query.uniqueResult();
query.uniqueResultOptional();
query.scroll().close();
query.scroll( ScrollMode.SCROLL_SENSITIVE ).close();
query.stream().close();
}
@NamedQuery( name = "hql-name", query = "select c.name from Contact c" )
@NamedQuery( name = "hql-first-name", query = "select c.name.first from Contact c" )
@NamedQuery( name = "hql-mutation", query = "delete from Contact" )
@Entity( name = "DummyEntity" )
@Table( name = "DummyEntity" )
public static class DummyEntity {
@Id
private Integer id;
@Basic
private String name;
private DummyEntity() {
// for use by Hibernate
}
public DummyEntity(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@ -1,79 +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.orm.test.query.sqm.untyped;
import org.hibernate.ScrollMode;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.query.SelectionQuery;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.domain.contacts.Contact;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
/**
* @author Steve Ebersole
*/
@DomainModel( standardModels = StandardDomainModel.CONTACTS )
@SessionFactory
public class BasicUntypedQueryTests {
@Test
public void typedEntitySelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
checkResults(
session.createSelectQuery( "select c from Contact c", Contact.class ),
session
);
} );
}
@Test
public void rawEntitySelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
checkResults(
session.createSelectQuery( "select c from Contact c" ),
session
);
} );
}
@Test
public void rawScalarSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
checkResults(
session.createSelectQuery( "select c.name from Contact c" ),
session
);
} );
}
@Test
public void typedScalarSelectTest(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
checkResults(
session.createSelectQuery( "select c.name from Contact c", Contact.Name.class ),
session
);
checkResults(
session.createSelectQuery( "select c.name.first from Contact c", String.class ),
session
);
} );
}
private void checkResults(SelectionQuery<?> query, SessionImplementor session) {
query.list();
query.getResultList();
query.uniqueResult();
query.uniqueResultOptional();
query.scroll().close();
query.scroll( ScrollMode.SCROLL_SENSITIVE ).close();
query.stream().close();
}
}