pull over "legacy 6.0" tests

This commit is contained in:
Steve Ebersole 2019-11-21 14:48:13 -06:00
parent e4f70d508f
commit 7576b51407
33 changed files with 1543 additions and 177 deletions

View File

@ -9,6 +9,5 @@ package org.hibernate.metamodel.mapping;
/**
* @author Steve Ebersole
*/
public interface EntityVersionMapping extends SingularAttributeMapping,
StateArrayContributorMapping, BasicValuedModelPart {
public interface EntityVersionMapping extends SingularAttributeMapping, StateArrayContributorMapping, BasicValuedModelPart {
}

View File

@ -7,8 +7,7 @@
package org.hibernate.metamodel.mapping;
/**
* Marker interface for parts of the application domain model that are virtual - do not
* actually exist in the model classes
* Marker interface for parts of the application domain model that do not actually exist in the model classes
*
* @author Steve Ebersole
*/

View File

@ -68,6 +68,9 @@ import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetti
/**
* Hibernate implementation of the JPA {@link javax.persistence.metamodel.Metamodel} contract.
*
* Really more of the mapping model then the domain model, though it does have reference to the `JpaMetamodel`
*
*
* @author Steve Ebersole
* @author Emmanuel Bernard
* @author Andrea Boriero
@ -700,6 +703,10 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
return (BasicType) sqmExpressable;
}
if ( sqmExpressable instanceof EmbeddedSqmPathSource ) {
throw new NotYetImplementedFor6Exception( "Resolution of embedded-valued SqmExpressable nodes not yet implemented" );
}
throw new UnsupportedOperationException( "Cannot determine proper mapping model expressable for " + sqmExpressable );
}
}

View File

@ -10,21 +10,16 @@ import java.util.List;
import java.util.function.Consumer;
import org.hibernate.Incubating;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.type.BasicType;
import org.hibernate.type.spi.TypeConfiguration;

View File

@ -84,12 +84,13 @@ import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmLiteralNull;
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.expression.SqmPathEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
import org.hibernate.query.sqm.tree.from.DowncastLocation;
@ -1266,14 +1267,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
// 2) TYPE( :someParam )
if ( ctx.entityTypeReference().parameter() != null ) {
// we have form (2)
return new SqmEntityType(
return new SqmParameterizedEntityType(
(SqmParameter) ctx.entityTypeReference().parameter().accept( this ),
creationContext.getNodeBuilder()
);
}
else if ( ctx.entityTypeReference().path() != null ) {
// we have form (1)
return new SqmEntityType(
return new SqmPathEntityType(
(SqmPath<?>) ctx.entityTypeReference().path().accept( this ),
creationContext.getNodeBuilder()
);

View File

@ -14,10 +14,8 @@ import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.query.spi.NativeQueryInterpreter;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
@ -28,22 +26,14 @@ import org.hibernate.query.hql.spi.SqmCreationOptions;
import org.hibernate.query.internal.QueryInterpretationCacheDisabledImpl;
import org.hibernate.query.internal.QueryInterpretationCacheStandardImpl;
import org.hibernate.query.named.NamedQueryRepository;
import org.hibernate.query.sqm.internal.DomainParameterXref;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.internal.SqmCreationOptionsStandard;
import org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;
import org.hibernate.query.sqm.produce.function.SqmFunctionRegistry;
import org.hibernate.query.sqm.spi.SqmCreationContext;
import org.hibernate.query.sqm.sql.SimpleSqmDeleteTranslator;
import org.hibernate.query.sqm.sql.SimpleSqmUpdateTranslator;
import org.hibernate.query.sqm.sql.SqmInsertSelectTranslator;
import org.hibernate.query.sqm.sql.SqmSelectTranslator;
import org.hibernate.query.sqm.sql.SqmTranslatorFactory;
import org.hibernate.query.sqm.sql.internal.StandardSqmDeleteTranslator;
import org.hibernate.query.sqm.sql.internal.StandardSqmInsertSelectTranslator;
import org.hibernate.query.sqm.sql.internal.StandardSqmSelectTranslator;
import org.hibernate.query.sqm.sql.internal.StandardSqmUpdateTranslator;
import org.hibernate.query.sqm.sql.StandardSqmTranslatorFactory;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
/**
* Aggregation and encapsulation of the components Hibernate uses
@ -53,20 +43,39 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
*/
@Incubating
public class QueryEngine {
public static QueryEngine from(
SessionFactoryImplementor sessionFactory,
MetadataImplementor metadata) {
final SqmCreationContext sqmCreationContext = sessionFactory;
final SessionFactoryOptions queryEngineOptions = sessionFactory.getSessionFactoryOptions();
final SqmCreationOptions sqmCreationOptions = new SqmCreationOptionsStandard( sessionFactory );
final Dialect dialect = sessionFactory.getJdbcServices().getDialect();
final HqlTranslator hqlTranslator = resolveHqlTranslator(
queryEngineOptions,
dialect,
sqmCreationContext,
sqmCreationOptions
);
final SqmTranslatorFactory sqmTranslatorFactory = resolveSqmTranslatorFactory( queryEngineOptions, dialect );
return new QueryEngine(
sessionFactory.getJpaMetamodel(),
sessionFactory.getServiceRegistry(),
sessionFactory.getSessionFactoryOptions(),
sessionFactory,
new SqmCreationOptionsStandard( sessionFactory ),
sessionFactory.getProperties(),
metadata.buildNamedQueryRepository( sessionFactory )
metadata.buildNamedQueryRepository( sessionFactory ),
hqlTranslator,
sqmTranslatorFactory,
sessionFactory.getServiceRegistry().getService( NativeQueryInterpreter.class ),
buildInterpretationCache( sessionFactory.getProperties() ),
dialect,
queryEngineOptions.getSqmFunctionRegistry(),
sessionFactory.getServiceRegistry()
);
}
private final JpaMetamodel jpaMetamodel;
private final NamedQueryRepository namedQueryRepository;
private final SqmCriteriaNodeBuilder criteriaBuilder;
private final HqlTranslator hqlTranslator;
@ -76,49 +85,141 @@ public class QueryEngine {
private final SqmFunctionRegistry sqmFunctionRegistry;
public QueryEngine(
JpaMetamodel domainModel,
ServiceRegistry serviceRegistry,
SessionFactoryOptions runtimeOptions,
SqmCreationContext sqmCreationContext,
SqmCreationOptions sqmCreationOptions,
Map properties,
NamedQueryRepository namedQueryRepository) {
final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
final Dialect dialect = jdbcEnvironment.getDialect();
JpaMetamodel jpaMetamodel,
NamedQueryRepository namedQueryRepository,
HqlTranslator hqlTranslator,
SqmTranslatorFactory sqmTranslatorFactory,
NativeQueryInterpreter nativeQueryInterpreter,
QueryInterpretationCache interpretationCache,
Dialect dialect,
SqmFunctionRegistry userDefinedRegistry,
ServiceRegistry serviceRegistry) {
this.jpaMetamodel = jpaMetamodel;
this.namedQueryRepository = namedQueryRepository;
this.hqlTranslator = resolveHqlTranslator(
runtimeOptions,
dialect,
sqmCreationContext,
sqmCreationOptions
);
this.sqmTranslatorFactory = resolveSqmTranslatorFactory(
runtimeOptions,
dialect,
sqmCreationContext,
sqmCreationOptions
);
this.sqmTranslatorFactory = sqmTranslatorFactory;
this.nativeQueryInterpreter = nativeQueryInterpreter;
this.interpretationCache = interpretationCache;
this.hqlTranslator = hqlTranslator;
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
this,
domainModel,
jpaMetamodel,
serviceRegistry
);
this.nativeQueryInterpreter = serviceRegistry.getService( NativeQueryInterpreter.class );
this.sqmFunctionRegistry = new SqmFunctionRegistry();
dialect.initializeFunctionRegistry( this );
if ( userDefinedRegistry != null ) {
userDefinedRegistry.overlay( sqmFunctionRegistry );
}
}
this.interpretationCache = buildInterpretationCache( properties );
/**
* Simplified constructor mainly meant for Quarkus use
*/
public QueryEngine(
JpaMetamodel jpaMetamodel,
boolean useStrictJpaCompliance,
NamedQueryRepository namedQueryRepository,
NativeQueryInterpreter nativeQueryInterpreter,
Dialect dialect,
ServiceRegistry serviceRegistry) {
this.jpaMetamodel = jpaMetamodel;
this.namedQueryRepository = namedQueryRepository;
this.sqmTranslatorFactory = null;
this.nativeQueryInterpreter = nativeQueryInterpreter;
this.sqmFunctionRegistry = new SqmFunctionRegistry();
dialect.initializeFunctionRegistry( this );
if ( runtimeOptions.getSqmFunctionRegistry() != null ) {
runtimeOptions.getSqmFunctionRegistry().overlay( sqmFunctionRegistry );
this.criteriaBuilder = new SqmCriteriaNodeBuilder(
this,
jpaMetamodel,
serviceRegistry
);
final SqmCreationContext sqmCreationContext = new SqmCreationContext() {
@Override
public JpaMetamodel getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
@Override
public QueryEngine getQueryEngine() {
return QueryEngine.this;
}
@Override
public NodeBuilder getNodeBuilder() {
return criteriaBuilder;
}
};
//noinspection Convert2Lambda
this.hqlTranslator = new StandardHqlTranslator(
sqmCreationContext,
new SqmCreationOptions() {
@Override
public boolean useStrictJpaCompliance() {
return useStrictJpaCompliance;
}
}
);
this.interpretationCache = buildInterpretationCache(
serviceRegistry.getService( ConfigurationService.class ).getSettings()
);
}
// public QueryEngine(
// JpaMetamodel domainModel,
// ServiceRegistry serviceRegistry,
// SessionFactoryOptions runtimeOptions,
// SqmCreationContext sqmCreationContext,
// SqmCreationOptions sqmCreationOptions,
// Map properties,
// NamedQueryRepository namedQueryRepository) {
// final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
// final JdbcEnvironment jdbcEnvironment = jdbcServices.getJdbcEnvironment();
// final Dialect dialect = jdbcEnvironment.getDialect();
//
// this.namedQueryRepository = namedQueryRepository;
//
// this.hqlTranslator = resolveHqlTranslator(
// runtimeOptions,
// dialect,
// sqmCreationContext,
// sqmCreationOptions
// );
//
// this.sqmTranslatorFactory = resolveSqmTranslatorFactory(
// runtimeOptions,
// dialect,
// sqmCreationContext,
// sqmCreationOptions
// );
//
// this.criteriaBuilder = new SqmCriteriaNodeBuilder(
// this,
// domainModel,
// serviceRegistry
// );
//
// this.nativeQueryInterpreter = serviceRegistry.getService( NativeQueryInterpreter.class );
//
// this.interpretationCache = buildInterpretationCache( properties );
//
// this.sqmFunctionRegistry = new SqmFunctionRegistry();
// dialect.initializeFunctionRegistry( this );
// if ( runtimeOptions.getSqmFunctionRegistry() != null ) {
// runtimeOptions.getSqmFunctionRegistry().overlay( sqmFunctionRegistry );
// }
// }
private static HqlTranslator resolveHqlTranslator(
SessionFactoryOptions runtimeOptions,
@ -136,11 +237,9 @@ public class QueryEngine {
return new StandardHqlTranslator( sqmCreationContext, sqmCreationOptions );
}
private SqmTranslatorFactory resolveSqmTranslatorFactory(
private static SqmTranslatorFactory resolveSqmTranslatorFactory(
SessionFactoryOptions runtimeOptions,
Dialect dialect,
SqmCreationContext sqmCreationContext,
SqmCreationOptions sqmCreationOptions) {
Dialect dialect) {
if ( runtimeOptions.getSqmTranslatorFactory() != null ) {
return runtimeOptions.getSqmTranslatorFactory();
}
@ -149,68 +248,7 @@ public class QueryEngine {
return dialect.getSqmTranslatorFactory();
}
return new SqmTranslatorFactory() {
@Override
public SqmSelectTranslator createSelectTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings domainParameterBindings,
LoadQueryInfluencers influencers,
SqlAstCreationContext creationContext) {
return new StandardSqmSelectTranslator(
queryOptions,
domainParameterXref,
domainParameterBindings,
influencers,
creationContext
);
}
@Override
public SimpleSqmDeleteTranslator createSimpleDeleteTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings domainParameterBindings,
LoadQueryInfluencers influencers,
SqlAstCreationContext creationContext) {
return new StandardSqmDeleteTranslator(
creationContext,
queryOptions,
domainParameterXref,
domainParameterBindings
);
}
@Override
public SqmInsertSelectTranslator createInsertSelectTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings domainParameterBindings,
LoadQueryInfluencers influencers,
SqlAstCreationContext creationContext) {
return new StandardSqmInsertSelectTranslator(
creationContext,
queryOptions,
domainParameterXref,
domainParameterBindings
);
}
@Override
public SimpleSqmUpdateTranslator createSimpleUpdateTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings queryParameterBindings,
LoadQueryInfluencers loadQueryInfluencers,
SessionFactoryImplementor factory) {
return new StandardSqmUpdateTranslator(
factory,
queryOptions,
domainParameterXref,
queryParameterBindings
);
}
};
return new StandardSqmTranslatorFactory();
}
private static QueryInterpretationCache buildInterpretationCache(Map properties) {

View File

@ -27,14 +27,14 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
import org.hibernate.query.sqm.tree.expression.SqmPathEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple;
@ -190,7 +190,9 @@ public interface SemanticQueryWalker<T> {
T visitEntityTypeLiteralExpression(SqmLiteralEntityType<?> expression);
T visitParameterizedEntityTypeExpression(SqmEntityType<?> expression);
T visitSqmPathEntityTypeExpression(SqmPathEntityType<?> expression);
T visitParameterizedEntityTypeExpression(SqmParameterizedEntityType<?> expression);
T visitUnaryOperationExpression(SqmUnaryOperation<?> expression);

View File

@ -32,13 +32,14 @@ import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
import org.hibernate.query.sqm.tree.expression.SqmPathEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple;
@ -594,7 +595,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
}
@Override
public Object visitParameterizedEntityTypeExpression(SqmEntityType expression) {
public Object visitParameterizedEntityTypeExpression(SqmParameterizedEntityType expression) {
return null;
}
@ -892,6 +893,11 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
public Object visitSqmPathEntityTypeExpression(SqmPathEntityType<?> expression) {
return null;
}
@Override
public Object visitFullyQualifiedClass(Class namedClass) {
return null;

View File

@ -35,13 +35,14 @@ import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
import org.hibernate.query.sqm.tree.expression.SqmCaseSearched;
import org.hibernate.query.sqm.tree.expression.SqmCaseSimple;
import org.hibernate.query.sqm.tree.expression.SqmCollectionSize;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.query.sqm.tree.expression.SqmNamedParameter;
import org.hibernate.query.sqm.tree.expression.SqmPathEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple;
@ -80,6 +81,7 @@ import org.hibernate.query.sqm.tree.update.SqmAssignment;
import org.hibernate.query.sqm.tree.update.SqmSetClause;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.ast.tree.expression.Expression;
/**
* Base support for an SQM walker
@ -457,7 +459,12 @@ public class BaseSemanticQueryWalker implements SemanticQueryWalker<Object> {
}
@Override
public Object visitParameterizedEntityTypeExpression(SqmEntityType expression) {
public Object visitSqmPathEntityTypeExpression(SqmPathEntityType<?> expression) {
return expression;
}
@Override
public Object visitParameterizedEntityTypeExpression(SqmParameterizedEntityType expression) {
return expression;
}

View File

@ -25,6 +25,7 @@ import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.metamodel.model.domain.AllowableParameterType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.internal.EmbeddedSqmPathSource;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.NavigablePath;
@ -794,12 +795,15 @@ public abstract class BaseSqmToSqlAstConverter
this.jdbcParameters.addParameters( jdbcParametersForSqm );
this.jdbcParamsBySqmParam.put( sqmParameter, jdbcParametersForSqm );
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter( sqmParameter );
final QueryParameterBinding<?> binding = domainParameterBindings.getBinding( queryParameter );
return new SqmParameterInterpretation(
sqmParameter,
domainParameterXref.getQueryParameter( sqmParameter ),
queryParameter,
jdbcParametersForSqm,
valueMapping,
domainParameterBindings::getBinding
qp -> binding
);
}
@ -871,6 +875,10 @@ public abstract class BaseSqmToSqlAstConverter
return (BasicValuedMapping) parameterSqmType;
}
if ( parameterSqmType instanceof EmbeddedSqmPathSource ) {
throw new NotYetImplementedFor6Exception( "Support for embedded-valued parameters not yet implemented" );
}
throw new ConversionException( "Could not determine ValueMapping for SqmParameter: " + sqmParameter );
}
@ -1391,10 +1399,8 @@ public abstract class BaseSqmToSqlAstConverter
}
@Override
public Object visitSubQueryExpression(SqmSubQuery sqmSubQuery) {
throw new NotYetImplementedFor6Exception( getClass() );
// final QuerySpec subQuerySpec = visitQuerySpec( sqmSubQuery.getQuerySpec() );
public QuerySpec visitSubQueryExpression(SqmSubQuery sqmSubQuery) {
return visitQuerySpec( sqmSubQuery.getQuerySpec() );
//
// final ExpressableType<?> expressableType = determineExpressableType( sqmSubQuery );
//

View File

@ -0,0 +1,86 @@
/*
* 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.sql;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.sqm.internal.DomainParameterXref;
import org.hibernate.query.sqm.sql.internal.StandardSqmDeleteTranslator;
import org.hibernate.query.sqm.sql.internal.StandardSqmInsertSelectTranslator;
import org.hibernate.query.sqm.sql.internal.StandardSqmSelectTranslator;
import org.hibernate.query.sqm.sql.internal.StandardSqmUpdateTranslator;
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
/**
* Standard implementation of the SqmTranslatorFactory
*
* @author Steve Ebersole
*/
public class StandardSqmTranslatorFactory implements SqmTranslatorFactory {
@Override
public SqmSelectTranslator createSelectTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings domainParameterBindings,
LoadQueryInfluencers influencers,
SqlAstCreationContext creationContext) {
return new StandardSqmSelectTranslator(
queryOptions,
domainParameterXref,
domainParameterBindings,
influencers,
creationContext
);
}
@Override
public SimpleSqmDeleteTranslator createSimpleDeleteTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings domainParameterBindings,
LoadQueryInfluencers influencers,
SqlAstCreationContext creationContext) {
return new StandardSqmDeleteTranslator(
creationContext,
queryOptions,
domainParameterXref,
domainParameterBindings
);
}
@Override
public SqmInsertSelectTranslator createInsertSelectTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings domainParameterBindings,
LoadQueryInfluencers influencers,
SqlAstCreationContext creationContext) {
return new StandardSqmInsertSelectTranslator(
creationContext,
queryOptions,
domainParameterXref,
domainParameterBindings
);
}
@Override
public SimpleSqmUpdateTranslator createSimpleUpdateTranslator(
QueryOptions queryOptions,
DomainParameterXref domainParameterXref,
QueryParameterBindings queryParameterBindings,
LoadQueryInfluencers loadQueryInfluencers,
SessionFactoryImplementor factory) {
return new StandardSqmUpdateTranslator(
factory,
queryOptions,
domainParameterXref,
queryParameterBindings
);
}
}

View File

@ -22,6 +22,7 @@ import org.hibernate.sql.ast.spi.SqlAstCreationContext;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.tree.expression.ColumnReference;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression;
import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.update.Assignment;
@ -39,7 +40,7 @@ public class BasicValuedPathInterpretation<T> implements AssignableSqmPathInterp
SqmBasicValuedSimplePath<T> sqmPath,
SqlAstCreationState sqlAstCreationState,
SemanticQueryWalker sqmWalker) {
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().findTableGroup( sqmPath.getLhs().getNavigablePath() );
final TableGroup tableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( sqmPath.getLhs().getNavigablePath() );
final BasicValuedModelPart mapping = (BasicValuedModelPart) tableGroup.getModelPart().findSubPart(
sqmPath.getReferencedPathSource().getPathName(),
@ -48,7 +49,7 @@ public class BasicValuedPathInterpretation<T> implements AssignableSqmPathInterp
final TableReference tableReference = tableGroup.resolveTableReference( mapping.getContainingTableExpression() );
final ColumnReference columnReference = (ColumnReference) sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
final Expression expression = sqlAstCreationState.getSqlExpressionResolver().resolveSqlExpression(
SqlExpressionResolver.createColumnReferenceKey(
tableReference,
mapping.getMappedColumnExpression()
@ -61,6 +62,19 @@ public class BasicValuedPathInterpretation<T> implements AssignableSqmPathInterp
)
);
final ColumnReference columnReference;
if ( expression instanceof ColumnReference ) {
columnReference = ( (ColumnReference) expression );
}
else if ( expression instanceof SqlSelectionExpression ) {
final Expression selectedExpression = ( (SqlSelectionExpression) expression ).getExpression();
assert selectedExpression instanceof ColumnReference;
columnReference = (ColumnReference) selectedExpression;
}
else {
throw new UnsupportedOperationException( "Unsupported basic-valued path expression : " + expression );
}
return new BasicValuedPathInterpretation<>( columnReference, sqmPath, mapping, tableGroup );
}

View File

@ -35,6 +35,7 @@ import org.hibernate.query.sqm.sql.SqmSelectTranslation;
import org.hibernate.query.sqm.sql.SqmSelectTranslator;
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPathEntityType;
import org.hibernate.query.sqm.tree.from.SqmAttributeJoin;
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiation;
import org.hibernate.query.sqm.tree.select.SqmDynamicInstantiationArgument;
@ -415,6 +416,15 @@ public class StandardSqmSelectTranslator
return new EntityTypeLiteral( mappingDescriptor );
}
@Override
public Expression visitSqmPathEntityTypeExpression(SqmPathEntityType<?> sqmExpression) {
return BasicValuedPathInterpretation.from(
sqmExpression,
this,
this
);
}
@Override
public Object visitFullyQualifiedClass(Class namedClass) {
throw new NotYetImplementedFor6Exception();

View File

@ -18,18 +18,16 @@ import org.hibernate.query.sqm.tree.select.SqmSelectableNode;
*
* @author Steve Ebersole
*/
public class SqmEntityType<T> extends AbstractSqmExpression<T> implements SqmSelectableNode<T> {
public class SqmParameterizedEntityType<T> extends AbstractSqmExpression<T> implements SqmSelectableNode<T> {
private final SqmExpression discriminatorSource;
public SqmEntityType(SqmParameter<T> parameterExpression, NodeBuilder nodeBuilder) {
super( parameterExpression.getAnticipatedType(), nodeBuilder );
this.discriminatorSource = parameterExpression;
public SqmExpression getDiscriminatorSource() {
return discriminatorSource;
}
public SqmEntityType(SqmPath<T> entityValuedPath, NodeBuilder nodeBuilder) {
//noinspection unchecked
super( entityValuedPath.getReferencedPathSource().sqmAs( EntityDomainType.class ), nodeBuilder );
this.discriminatorSource = entityValuedPath;
public SqmParameterizedEntityType(SqmParameter<T> parameterExpression, NodeBuilder nodeBuilder) {
super( parameterExpression.getAnticipatedType(), nodeBuilder );
this.discriminatorSource = parameterExpression;
}
@Override

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.tree.expression;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**
* @author Steve Ebersole
*/
public class SqmPathEntityType<T> extends SqmBasicValuedSimplePath<T> {
public SqmPathEntityType(SqmPath<T> entityValuedPath, NodeBuilder nodeBuilder) {
super(
entityValuedPath.getNavigablePath().append( EntityDiscriminatorMapping.ROLE_NAME ),
// todo (6.0) : need a BasicValueSqmPathSource representing the discriminator for this to work.
null,
entityValuedPath,
nodeBuilder
);
throw new NotYetImplementedFor6Exception( getClass() );
// //noinspection unchecked
// super(
// ,
// ( (EntityDomainType<T>) entityValuedPath.getNodeType() ).getDiscriminatorDescriptor(),
// entityValuedPath,
// nodeBuilder
// );
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitSqmPathEntityTypeExpression( this );
}
}

View File

@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.hibernate.metamodel.mapping.MappingModelExpressable;
import org.hibernate.sql.ast.spi.SqlAstTreeHelper;
import org.hibernate.sql.ast.spi.SqlAstWalker;
import org.hibernate.sql.ast.tree.SqlAstNode;
@ -22,7 +23,7 @@ import org.hibernate.sql.ast.tree.predicate.PredicateContainer;
/**
* @author Steve Ebersole
*/
public class QuerySpec implements SqlAstNode, PredicateContainer, CteConsumer {
public class QuerySpec implements SqlAstNode, PredicateContainer, Expression, CteConsumer {
private final boolean isRoot;
private final FromClause fromClause;
@ -105,4 +106,12 @@ public class QuerySpec implements SqlAstNode, PredicateContainer, CteConsumer {
public void accept(SqlAstWalker sqlTreeWalker) {
sqlTreeWalker.visitQuerySpec( this );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Expression
@Override
public MappingModelExpressable getExpressionType() {
return null;
}
}

View File

@ -42,11 +42,18 @@ public class BasicResultAssembler<J> implements DomainResultAssembler<J> {
this.valueConverter = valueConverter;
}
/**
* Access to the raw value (unconverted, if a converter applied)
*/
public Object extractRawValue(RowProcessingState rowProcessingState) {
return rowProcessingState.getJdbcValue( valuesArrayPosition );
}
@Override
public J assemble(
RowProcessingState rowProcessingState,
JdbcValuesSourceProcessingOptions options) {
Object jdbcValue = rowProcessingState.getJdbcValue( valuesArrayPosition );
Object jdbcValue = extractRawValue( rowProcessingState );
SqlResultsLogger.INSTANCE.debugf( "Extracted JDBC value [%d] - [%s]", valuesArrayPosition, jdbcValue );

View File

@ -8,10 +8,13 @@ package org.hibernate.sql.results.internal.domain.composite;
import java.util.function.Consumer;
import org.hibernate.LockMode;
import org.hibernate.engine.FetchTiming;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.query.NavigablePath;
import org.hibernate.sql.ast.JoinType;
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
import org.hibernate.sql.results.internal.domain.AbstractFetchParent;
import org.hibernate.sql.results.spi.AssemblerCreationState;
import org.hibernate.sql.results.spi.CompositeResultMappingNode;
@ -44,9 +47,25 @@ public class CompositeFetch extends AbstractFetchParent implements CompositeResu
this.fetchTiming = fetchTiming;
this.nullable = nullable;
creationState.getSqlAstCreationState().getFromClauseAccess().registerTableGroup(
creationState.getSqlAstCreationState().getFromClauseAccess().resolveTableGroup(
getNavigablePath(),
creationState.getSqlAstCreationState().getFromClauseAccess().findTableGroup( fetchParent.getNavigablePath() )
np -> {
final TableGroupJoin tableGroupJoin = getFetchContainer().createTableGroupJoin(
getNavigablePath(),
creationState.getSqlAstCreationState()
.getFromClauseAccess()
.findTableGroup( fetchParent.getNavigablePath() ),
null,
nullable ? JoinType.LEFT : JoinType.INNER,
LockMode.NONE,
stem -> creationState.getSqlAliasBaseManager().createSqlAliasBase( stem ),
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
creationState.getSqlAstCreationState().getCreationContext()
);
return tableGroupJoin.getJoinedGroup();
}
);
afterInitialize( creationState );

View File

@ -0,0 +1,15 @@
/*
* 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
*/
/**
* Tests verifying that expectations of various integrations continue to work.
*
* E.g. make sure that SQM trees can
* continue to be built without access to SessionFactory; Quarkus and others use this to translate HQL statements
* into SQM at boot time or even build time
*/
package org.hibernate.orm.test.intg;

View File

@ -0,0 +1,145 @@
/*
* 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.intg.sqm;
import java.util.Collections;
import java.util.Optional;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl;
import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.hql.internal.StandardHqlTranslator;
import org.hibernate.query.hql.spi.SqmCreationOptions;
import org.hibernate.query.internal.NamedQueryRepositoryImpl;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.spi.SqmCreationContext;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* Tests making sure that HQL queries can fully be translated without a SessionFactory.
*
* todo (6.0) : have a way to directly load these translations into the {@link org.hibernate.query.named.NamedQueryRepository}
* directly. For example Quarkus could store its build-time translations and directly here during boot-strap of the SF
*
* @author Steve Ebersole
*/
@ServiceRegistry
@DomainModel( standardModels = StandardDomainModel.RETAIL )
public class HqlTranslationNoFactoryTests {
@Test
@FailureExpected( reason = "Building the JpaDomain")
public void testHqlTranslationNoSessionFactory(DomainModelScope modelScope, ServiceRegistryScope registryScope) {
final String hql = "select a from SalesAssociate a";
final HqlTranslator hqlTranslator = buildHqlTranslator( modelScope, registryScope );
final SqmStatement sqmStatement = hqlTranslator.translate( hql );
assert sqmStatement != null;
}
private HqlTranslator buildHqlTranslator(DomainModelScope modelScope, ServiceRegistryScope registryScope) {
final MetadataImplementor bootModel = modelScope.getDomainModel();
final TypeConfiguration typeConfiguration = bootModel.getTypeConfiguration();
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( typeConfiguration );
// todo (6.0) (quarkus) : we should limit the type of the last argument here from `RuntimeModelCreationContext`
// which assumes access to SessionFactory
jpaMetamodel.processJpa(
bootModel,
Collections.emptyMap(),
JpaStaticMetaModelPopulationSetting.ENABLED,
Collections.emptyList(),
new RuntimeModelCreationContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
throw new UnsupportedOperationException( "SessionFactory not available" );
}
@Override
public BootstrapContext getBootstrapContext() {
return typeConfiguration.getMetadataBuildingContext().getBootstrapContext();
}
@Override
public MetadataImplementor getBootModel() {
return modelScope.getDomainModel();
}
@Override
public DomainMetamodel getDomainModel() {
throw new UnsupportedOperationException( "DomainMetamodel not available" );
}
}
);
Optional<QueryEngine> queryEngineAccess = Optional.empty();
// todo (6.0) (quarkus) : this circularity is problematic as well
// between `SqmCreationContext#getQueryEngine` and the `SqmCreationContext` passed to `#QueryEngine`
final SqmCreationContext sqmCreationContext = new SqmCreationContext() {
@Override
public JpaMetamodel getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public QueryEngine getQueryEngine() {
return queryEngineAccess.orElseThrow( () -> new RuntimeException( "Unexpected access to `SqmCreationContext#getQueryEngine`" ) );
}
};
// we don't want strict JPA query compliance
final SqmCreationOptions sqmCreationOptions = () -> false;
final QueryEngine queryEngine = new QueryEngine(
jpaMetamodel,
// we don't want strict JPA query compliance
false,
new NamedQueryRepositoryImpl( Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap() ),
// NativeQueryInterpreter
null,
// this is exclusively to build the SqmFunctionRegistry, maybe Quarkus should just build it directly and pass
registryScope.getRegistry().getService( JdbcServices.class ).getDialect(),
registryScope.getRegistry()
);
return new StandardHqlTranslator(
new SqmCreationContext() {
@Override
public JpaMetamodel getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public QueryEngine getQueryEngine() {
return queryEngine;
}
},
sqmCreationOptions
);
}
}

View File

@ -0,0 +1,123 @@
/*
* 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.hql;
import java.util.Date;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Chris Cranford
*/
public class DateQueryParameterTest extends SessionFactoryBasedFunctionalTest {
@Entity(name = "DateEntity")
public static class DateEntity {
@Id
@GeneratedValue
private Integer id;
private Date timestamp;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
}
private long timestamp1;
private long timestamp2;
private long timestamp3;
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { DateEntity.class };
}
@Test
public void testDateEntityQuery() throws Exception {
try {
timestamp1 = System.currentTimeMillis();
inTransaction(
session -> {
final DateEntity entity = new DateEntity();
entity.setTimestamp( new Date() );
session.save( entity );
}
);
timestamp2 = System.currentTimeMillis();
Thread.sleep( 1100 );
inTransaction(
session -> {
final DateEntity entity = new DateEntity();
entity.setTimestamp( new Date() );
session.save( entity );
}
);
timestamp3 = System.currentTimeMillis();
inTransaction(
session -> {
// Test nothing before timestamp1
List<DateEntity> results = session
.createQuery( "SELECT e FROM DateEntity e WHERE e.timestamp < :value", DateEntity.class )
.setParameter( "value", new Date( timestamp1 ) )
.getResultList();
assertEquals( results.size(), 0 );
// Test only one entry before timestamp2
results = session
.createQuery( "SELECT e FROM DateEntity e WHERE e.timestamp < : value", DateEntity.class )
.setParameter( "value", new Date( timestamp2 ) )
.getResultList();
assertEquals( results.size(), 1 );
// Test two entries before timestamp3
results = session
.createQuery( "SELECT e FROM DateEntity e WHERE e.timestamp < : value", DateEntity.class )
.setParameter( "value", new Date( timestamp3 ) )
.getResultList();
assertEquals( results.size(), 2 );
}
);
}
catch ( InterruptedException e ) {
throw new RuntimeException( "Failed to thread sleep properly", e );
}
}
@AfterEach
public void cleanUpData() {
inTransaction(
session -> {
session.createQuery( "delete DateEntity" ).executeUpdate();
}
);
}
}

View File

@ -0,0 +1,159 @@
/*
* 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.hql;
import java.util.List;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Andrea Boriero
*/
@FailureExpected( reason = "Support for embedded-valued parameters not yet implemented" )
public class EmbeddableAsParameterTest extends SessionFactoryBasedFunctionalTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
Person.class,
};
}
@Test
public void testAsParameterInWhereClause() {
inTransaction(
session -> {
List results = session.createQuery( "select p from Person p where p.name = :name" ).
setParameter( "name", new Name( "Fab", "Fab" ) ).list();
assertThat( results.size(), is( 1 ) );
}
);
}
@Test
public void testAsParameterReuseInWhereClause() {
inTransaction(
session -> {
List results = session.createQuery( "select p from Person p where p.name = :name or p.name = :name " ).
setParameter( "name", new Name( "Fab", "Fab" ) ).list();
assertThat( results.size(), is( 1 ) );
}
);
}
@BeforeEach
public void setUp() {
inTransaction(
session -> {
Person person = new Person(
1,
new Name( "Fab", "Fab" ),
33
);
session.save( person );
} );
}
@AfterEach
public void tearDown() {
inTransaction(
session -> {
session.createQuery( "delete Person" ).executeUpdate();
}
);
}
@Entity(name = "Person")
public static class Person {
@Id
private Integer id;
private Name name;
private Integer age;
public Person() {
}
@Override
public int hashCode() {
return super.hashCode();
}
public Person(Integer id, Name name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
@Embeddable
public static class Name {
private String firstName;
private String secondName;
public Name() {
}
public Name(String firstName, String secondName) {
this.firstName = firstName;
this.secondName = secondName;
}
public String getFirstName() {
return firstName;
}
public String getSecondName() {
return secondName;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
}

View File

@ -1,22 +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.hql;
import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest;
import org.hibernate.orm.test.query.sqm.domain.Person;
/**
* @author Steve Ebersole
*/
public class FunctionTests extends BaseSqmUnitTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { Person.class };
}
}

View File

@ -0,0 +1,150 @@
/*
* 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.hql;
import java.time.LocalDate;
import java.time.Month;
import java.util.List;
import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
public class NamedHqlQueriesTest extends SessionFactoryBasedFunctionalTest {
final VideoGame GOD_OF_WAR = new VideoGame( "GOW_2018", "God of war", LocalDate.of( 2018, Month.APRIL, 20 ) );
final VideoGame THE_LAST_OF_US = new VideoGame(
"TLOU_2013", "The last of us", LocalDate.of( 2013, Month.JUNE, 14 ) );
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
VideoGame.class,
};
}
@Test
public void testQueryWithoutParameters() {
inTransaction(
session -> {
List<VideoGame> results = session.createNamedQuery( "videogames" ).list();
assertThat( results, containsInAnyOrder( GOD_OF_WAR, THE_LAST_OF_US ) );
} );
}
@Test
public void testQueryWithSingleParameters() {
inTransaction(
session -> {
List<VideoGame> results = session.createNamedQuery( "title" )
.setParameter("title", GOD_OF_WAR.getTitle() )
.list();
assertThat( results, contains( GOD_OF_WAR ) );
} );
}
@BeforeEach
public void setUp() {
inTransaction(
session -> {
session.save( GOD_OF_WAR );
session.save( THE_LAST_OF_US );
} );
}
@AfterEach
public void tearDown() {
inTransaction(
session -> {
session.createQuery( "from VideoGame vg" )
.list()
.forEach( vg -> session.delete( vg ) );
} );
}
@Entity(name = "VideoGame")
@NamedQueries({
@NamedQuery(name = "videogames", query = "select vg from VideoGame vg"),
@NamedQuery(name = "title", query = "select vg from VideoGame vg where vg.title=:title")
})
static class VideoGame {
public VideoGame() {
}
public VideoGame(String id, String title, LocalDate releaseDate) {
this.id = id;
this.title = title;
this.releaseDate = releaseDate;
}
@Id
private String id;
private String title;
private LocalDate releaseDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public LocalDate getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(LocalDate releaseDate) {
this.releaseDate = releaseDate;
}
@Override
public String toString() {
return title;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
VideoGame videoGame = (VideoGame) o;
return Objects.equals( id, videoGame.id ) &&
Objects.equals( title, videoGame.title ) &&
Objects.equals( releaseDate, videoGame.releaseDate );
}
@Override
public int hashCode() {
return Objects.hash( id, title, releaseDate );
}
}
}

View File

@ -0,0 +1,80 @@
/*
* 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.hql;
import java.util.Calendar;
import java.util.List;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.domain.gambit.SimpleEntity;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Andrea Boriero
*/
public class SubqueryLimitOffsetTest extends SessionFactoryBasedFunctionalTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
SimpleEntity.class,
};
}
@Test
public void testSubqueryLimitOffset() {
inTransaction(
session -> {
List results = session.createQuery(
"select o from SimpleEntity o where o.someString = ( select oSub.someString from SimpleEntity oSub order by oSub.someString limit 1 )" )
.list();
assertThat( results.size(), is( 2 ) );
} );
}
@BeforeEach
public void setUp() {
inTransaction(
session -> {
SimpleEntity entity = new SimpleEntity(
1,
Calendar.getInstance().getTime(),
null,
Integer.MAX_VALUE,
Long.MAX_VALUE,
"some"
);
session.save( entity );
SimpleEntity second_entity = new SimpleEntity(
2,
Calendar.getInstance().getTime(),
null,
Integer.MIN_VALUE,
Long.MAX_VALUE,
"some"
);
session.save( second_entity );
} );
}
@AfterEach
public void tearDown() {
inTransaction(
session -> {
session.createQuery( "from SimpleEntity e" )
.list()
.forEach( simpleEntity -> session.delete( simpleEntity ) );
} );
}
}

View File

@ -0,0 +1,36 @@
/*
* 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.exec;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.domain.gambit.SimpleEntity;
import org.junit.jupiter.api.Test;
/**
* @author Steve Ebersole
*/
public class CrossJoinTest extends SessionFactoryBasedFunctionalTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
SimpleEntity.class,
};
}
@Test
public void testSimpleCrossJoin() {
inTransaction(
session -> {
session.createQuery(
"from SimpleEntity e1, SimpleEntity e2 where e1.id = e2.id and e1.someDate = {d '2018-01-01'}" )
.list();
}
);
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.exec;
import java.util.List;
import org.hibernate.boot.MetadataSources;
import org.hibernate.query.spi.QueryImplementor;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.domain.retail.DomesticVendor;
import org.hibernate.testing.orm.domain.retail.ForeignVendor;
import org.hibernate.testing.orm.domain.retail.Vendor;
import org.hibernate.testing.orm.junit.BaseSessionFactoryFunctionalTest;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.hamcrest.Matcher;
import static org.hamcrest.CoreMatchers.either;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Steve Ebersole
*/
@SuppressWarnings("WeakerAccess")
public class DiscriminatorTests extends BaseSessionFactoryFunctionalTest {
@Override
protected void applyMetadataSources(MetadataSources metadataSources) {
StandardDomainModel.RETAIL.getDescriptor().applyDomainModel( metadataSources );
}
@BeforeEach
public void setUpTestData() {
inTransaction(
session -> {
session.save( new ForeignVendor( 1, "ForeignVendor", "Vendor, Inc." ) );
session.save( new DomesticVendor( 2, "DomesticVendor", "Vendor, Inc." ) );
}
);
}
@AfterEach
public void cleanUpTestData() {
inTransaction(
session -> {
session.createQuery( "delete Vendor" ).executeUpdate();
}
);
}
@Test
@FailureExpected( reason = "selection of discriminator not yet implemented" )
public void testSelection() {
inTransaction(
session -> {
final QueryImplementor query = session.createQuery( "select type( v ) from Vendor v" );
final List list = query.list();
assertThat( list.size(), is( 2 ) );
for ( Object o : list ) {
assertThat(
o,
(Matcher) either( is( DomesticVendor.class.getName() ) )
.or( is( ForeignVendor.class.getName() ) )
);
}
assert list.contains( DomesticVendor.class.getName() );
assert list.contains( ForeignVendor.class.getName() );
}
);
}
}

View File

@ -0,0 +1,87 @@
/*
* 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.exec;
import java.util.Calendar;
import java.util.List;
import org.hibernate.orm.test.query.sqm.BaseSqmUnitTest;
import org.hibernate.testing.orm.domain.gambit.SimpleEntity;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Steve Ebersole
*/
public class FunctionTests extends BaseSqmUnitTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] { SimpleEntity.class };
}
@Override
protected boolean exportSchema() {
return true;
}
@Test
@FailureExpected( reason = "Function support not yet implemented" )
public void testSubstrInsideConcat() {
inTransaction(
session -> {
List<Object> results = session.createQuery(
"select concat('111', concat('222222', '1')) from SimpleEntity s where s.id = :id" )
.setParameter( "id", 1 )
.list();
assertThat( results.size(), is( 1 ) );
assertThat( results.get( 0 ), is( "1112222221" ) );
} );
}
@BeforeEach
public void setUp() {
inTransaction(
session -> {
SimpleEntity entity = new SimpleEntity(
1,
Calendar.getInstance().getTime(),
null,
Integer.MAX_VALUE,
Long.MAX_VALUE,
null
);
session.save( entity );
SimpleEntity second_entity = new SimpleEntity(
2,
Calendar.getInstance().getTime(),
null,
Integer.MIN_VALUE,
Long.MAX_VALUE,
null
);
session.save( second_entity );
} );
}
@AfterEach
public void tearDown() {
inTransaction(
session -> {
session.createQuery( "delete SimpleEntity" ).executeUpdate();
}
);
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.exec;
import org.hibernate.boot.MetadataSources;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.junit.jupiter.api.Test;
/**
* @author Steve Ebersole
*/
public class LiteralTests extends SessionFactoryBasedFunctionalTest {
@Override
protected void applyMetadataSources(MetadataSources metadataSources) {
StandardDomainModel.GAMBIT.getDescriptor().applyDomainModel( metadataSources );
}
@Test
public void testTimestampLiteral() {
inTransaction(
session -> {
session.createQuery( "from EntityOfBasics e1 where e1.theTimestamp = {ts '2018-01-01T12:30:00'}" )
.list();
}
);
}
@Test
public void testDateLiteral() {
inTransaction(
session -> {
session.createQuery( "from EntityOfBasics e1 where e1.theDate = {d '2018-01-01'}" ).list();
}
);
}
@Test
public void testTimeLiteral() {
inTransaction(
session -> {
session.createQuery( "from EntityOfBasics e1 where e1.theTime = {t '12:30:00'}" ).list();
}
);
}
}

View File

@ -0,0 +1,71 @@
/*
* 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.exec;
import org.hibernate.boot.MetadataSources;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.junit.jupiter.api.Test;
/**
* Tests for order-by clauses
* @author Steve Ebersole
*/
public class OrderingTests extends SessionFactoryBasedFunctionalTest {
@Override
protected void applyMetadataSources(MetadataSources metadataSources) {
StandardDomainModel.RETAIL.getDescriptor().applyDomainModel( metadataSources );
}
@Test
public void testBasicOrdering() {
inTransaction(
session -> {
session.createQuery( "from SalesAssociate p order by p.name.familiarName" )
.list();
}
);
}
@Test
@TestForIssue( jiraKey = "HHH-1356" )
@FailureExpected( reason = "functions not yet implemented" )
public void testFunctionBasedOrdering() {
inTransaction(
session -> {
session.createQuery( "from SalesAssociate p order by upper( p.name.familiarName )" )
.list();
}
);
}
@Test
@TestForIssue( jiraKey = "HHH-11688" )
public void testSelectAliasOrdering() {
inTransaction(
session -> {
session.createQuery( "select v.name as n from Vendor v order by n" )
.list();
}
);
}
@Test
@TestForIssue( jiraKey = "HHH-11688" )
public void testSelectPositionOrdering() {
inTransaction(
session -> {
session.createQuery( "select v.name as n from Vendor v order by 1" )
.list();
}
);
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.exec;
import org.hibernate.boot.MetadataSources;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.junit.jupiter.api.Test;
/**
* @author Steve Ebersole
*/
public class ParameterTest extends SessionFactoryBasedFunctionalTest {
@Override
protected void applyMetadataSources(MetadataSources metadataSources) {
StandardDomainModel.RETAIL.getDescriptor().applyDomainModel( metadataSources );
}
@Test
public void testReusedNamedParam() {
inTransaction(
session -> {
session.createQuery( "from SalesAssociate p where p.name.familiarName = :name or p.name.familyName = :name" )
.setParameter( "name", "a name" )
.list();
}
);
}
@Test
public void testReusedOrdinalParam() {
inTransaction(
session -> {
session.createQuery( "from SalesAssociate p where p.name.familiarName = ?1 or p.name.familyName = ?1" )
.setParameter( 1, "a name" )
.list();
}
);
}
}

View File

@ -0,0 +1,83 @@
/*
* 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.exec;
import java.util.List;
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
import org.hibernate.testing.orm.domain.gambit.BasicEntity;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* @author Chris Cranford
*/
public class SubQueryTest extends SessionFactoryBasedFunctionalTest {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
BasicEntity.class
};
}
@BeforeAll
public void prepareData() {
inTransaction(
session -> {
BasicEntity entity1 = new BasicEntity( 1, "e1" );
BasicEntity entity2 = new BasicEntity( 2, "e2" );
BasicEntity entity3 = new BasicEntity( 3, "e1" );
session.save( entity1 );
session.save( entity2 );
session.save( entity3 );
}
);
}
@Test
@FailureExpected( reason = "function support not yet implemented" )
public void testSubQueryWithMaxFunction() {
inTransaction(
session -> {
final String hql = "SELECT e FROM BasicEntity e WHERE e.id = " +
"(SELECT max(e1.id) FROM BasicEntity e1 WHERE e1.data = :data)";
List<BasicEntity> results = session
.createQuery( hql, BasicEntity.class )
.setParameter( "data", "e1" )
.getResultList();
assertThat( results.size(), is( 1 ) );
assertThat( results.get( 0 ).getId(), is( 3 ) );
assertThat( results.get( 0 ).getData(), is( "e1" ) );
}
);
}
@Test
@FailureExpected( reason = "function support not yet implemented" )
public void testSubQueryWithMinFunction() {
inTransaction(
session -> {
final String hql = "SELECT e FROM BasicEntity e WHERE e.id = " +
"(SELECT min(e1.id) FROM BasicEntity e1 WHERE e1.data = :data)";
List<BasicEntity> results = session
.createQuery( hql, BasicEntity.class )
.setParameter( "data", "e1" )
.getResultList();
assertThat( results.size(), is( 1 ) );
assertThat( results.get( 0 ).getId(), is( 1 ) );
assertThat( results.get( 0 ).getData(), is( "e1" ) );
}
);
}
}

View File

@ -7,6 +7,7 @@
package org.hibernate.testing.orm.junit;
import java.util.function.Consumer;
import java.util.function.Function;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.service.Service;
@ -28,4 +29,16 @@ public interface ServiceRegistryScope {
action.accept( service );
}
default <R, S extends Service> R fromService(Class<S> role, Function<S,R> action) {
assert role != null;
final S service = getRegistry().getService( role );
if ( service == null ) {
throw new IllegalArgumentException( "Could not locate requested service - " + role.getName() );
}
return action.apply( service );
}
}