6 - SQM based on JPA type system

This commit is contained in:
Steve Ebersole 2019-05-24 11:21:47 -05:00 committed by Andrea Boriero
parent 4c058d8e9c
commit 163cc53318
53 changed files with 1133 additions and 160 deletions

View File

@ -17,7 +17,8 @@ import org.hibernate.query.sqm.SqmExpressable;
*
* @author Steve Ebersole
*/
public interface BasicDomainType<J> extends SimpleDomainType<J>, BasicType<J>, SqmExpressable<J> {
public interface BasicDomainType<J>
extends SimpleDomainType<J>, BasicType<J>, SqmExpressable<J>, AllowableOutputParameterType<J>, AllowableFunctionReturnType<J> {
@Override
default PersistenceType getPersistenceType() {
return PersistenceType.BASIC;

View File

@ -18,7 +18,7 @@ import org.hibernate.Incubating;
* @author Steve Ebersole
*/
@Incubating
public interface ParameterMetadata<P extends QueryParameter<?>> {
public interface ParameterMetadata {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
// General purpose
@ -35,7 +35,7 @@ public interface ParameterMetadata<P extends QueryParameter<?>> {
*
* @throws IllegalArgumentException if no parameter is registered under that name
*/
P getQueryParameter(String name);
<T> QueryParameter<T> getQueryParameter(String name);
/**
* Resolve the QueryParameter reference registered here under the
@ -45,7 +45,7 @@ public interface ParameterMetadata<P extends QueryParameter<?>> {
*
* @throws IllegalArgumentException if no parameter is registered under that label
*/
P getQueryParameter(int positionLabel);
<T> QueryParameter<T> getQueryParameter(int positionLabel);
/**
* A deeper resolution attempt from a JPA parameter reference to Hibernate's
@ -54,19 +54,19 @@ public interface ParameterMetadata<P extends QueryParameter<?>> {
* According to the spec, only Parameter references obtained from the provider
* are valid.
*/
P resolve(Parameter param);
<T> QueryParameter<T> resolve(Parameter<T> param);
/**
* Is this parameter reference registered in this collection?
*/
boolean containsReference(P parameter);
boolean containsReference(QueryParameter<?> parameter);
Set<P> getRegistrations();
Set<? extends QueryParameter<?>> getRegistrations();
/**
* General purpose visitation using functional
*/
void visitRegistrations(Consumer<P> action);
void visitRegistrations(Consumer<? extends QueryParameter<?>> action);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

View File

@ -4,7 +4,7 @@
* 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;
package org.hibernate.query;
import org.hibernate.HibernateException;

View File

@ -10,6 +10,7 @@ import javax.persistence.criteria.Path;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.PathException;
/**
* API extension to the JPA {@link Path} contract

View File

@ -23,22 +23,25 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.ComparisonOperator;
import org.hibernate.query.PathException;
import org.hibernate.query.QueryLogger;
import org.hibernate.query.SemanticException;
import org.hibernate.query.TrimSpec;
import org.hibernate.query.UnaryArithmeticOperator;
import org.hibernate.query.hql.DotIdentifierConsumer;
import org.hibernate.query.sqm.LiteralNumberFormatException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.ParsingException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
@ -62,38 +65,26 @@ import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.delete.SqmDeleteStatement;
import org.hibernate.query.sqm.tree.domain.SqmBagJoin;
import org.hibernate.query.sqm.tree.domain.SqmIndexedCollectionAccessPath;
import org.hibernate.query.sqm.tree.domain.SqmListJoin;
import org.hibernate.query.sqm.tree.domain.SqmMapEntryReference;
import org.hibernate.query.sqm.tree.domain.SqmMapJoin;
import org.hibernate.query.sqm.tree.domain.SqmMaxElementPath;
import org.hibernate.query.sqm.tree.domain.SqmMaxIndexPath;
import org.hibernate.query.sqm.tree.domain.SqmMinElementPath;
import org.hibernate.query.sqm.tree.domain.SqmMinIndexPath;
import org.hibernate.query.sqm.tree.domain.SqmNavigableReference;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
import org.hibernate.query.sqm.tree.domain.SqmSetJoin;
import org.hibernate.query.sqm.tree.domain.SqmSingularJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedBagJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedListJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedMapJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
import org.hibernate.query.sqm.tree.domain.SqmTreatedSetJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedSingularJoin;
import org.hibernate.query.sqm.tree.expression.LiteralHelper;
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.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.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmUnaryOperation;
import org.hibernate.query.sqm.tree.expression.function.SqmCastTarget;
@ -138,7 +129,6 @@ import org.hibernate.query.sqm.tree.select.SqmSelection;
import org.hibernate.query.sqm.tree.select.SqmSortSpecification;
import org.hibernate.query.sqm.tree.select.SqmSubQuery;
import org.hibernate.query.sqm.tree.update.SqmUpdateStatement;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.jboss.logging.Logger;
@ -336,7 +326,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
log.debugf(
"Generated implicit alias [%s] for INSERT target [%s]",
alias,
targetType.getEntityName()
targetType.getHibernateEntityName()
);
insertStatement.setSelectQuerySpec( visitQuerySpec( ctx.querySpec() ) );
@ -480,7 +470,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new SemanticException( "limit and offset clause require an order-by clause when used in sub-query" );
}
//noinspection unchecked
sqmQuerySpec.setOffsetExpression( visitOffsetClause( ctx.offsetClause() ) );
//noinspection unchecked
sqmQuerySpec.setLimitExpression( visitLimitClause( ctx.limitClause() ) );
}
@ -493,6 +485,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
// the root and each non-fetched-join was selected. For now, here, we simply
// select the root
final SqmSelectClause selectClause = new SqmSelectClause( false, creationContext.getNodeBuilder() );
//noinspection unchecked
fromClause.visitRoots(
sqmRoot -> selectClause.addSelection(
new SqmSelection( sqmRoot, sqmRoot.getExplicitAlias(), creationContext.getNodeBuilder() )
@ -530,6 +523,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final String resultIdentifier = visitResultIdentifier( ctx.resultIdentifier() );
final SqmSelectableNode selectableNode = visitSelectableNode( ctx );
//noinspection unchecked
final SqmSelection selection = new SqmSelection(
selectableNode,
resultIdentifier,
@ -1034,6 +1028,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
join.setExplicitAlias( alias );
if ( join instanceof SqmEntityJoin ) {
//noinspection unchecked
sqmRoot.addSqmJoin( join );
}
else {
@ -1080,7 +1075,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new UnsupportedOperationException();
}
public void consumeJpaCollectionJoin(HqlParser.JpaCollectionJoinContext ctx) {
@SuppressWarnings("WeakerAccess")
protected void consumeJpaCollectionJoin(HqlParser.JpaCollectionJoinContext ctx) {
// todo (6.0) : this should always make sure the collection tables are joined
// ideally via specialized DotIdentifierConsumer
identifierConsumerStack.push( new BasicDotIdentifierConsumer( processingStateStack::getCurrent ) );
@ -1252,6 +1248,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
listExpressions.add( listItemExpression );
}
//noinspection unchecked
return new SqmInListPredicate( testExpression, listExpressions, creationContext.getNodeBuilder() );
}
finally {
@ -1262,7 +1259,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final HqlParser.SubQueryInListContext subQueryContext = (HqlParser.SubQueryInListContext) ctx.inList();
final SqmExpression subQueryExpression = (SqmExpression) subQueryContext.expression().accept( this );
if ( !SqmSubQuery.class.isInstance( subQueryExpression ) ) {
if ( !(subQueryExpression instanceof SqmSubQuery) ) {
throw new ParsingException(
"Was expecting a SubQueryExpression, but found " + subQueryExpression.getClass().getSimpleName()
+ " : " + subQueryContext.expression().toString()
@ -1283,24 +1280,24 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@Override
@SuppressWarnings("unchecked")
public Object visitEntityTypeExpression(HqlParser.EntityTypeExpressionContext ctx) {
// can be one of 2 forms:
// 1) TYPE( some.path )
// 2) TYPE( :someParam )
if ( ctx.entityTypeReference().parameter() != null ) {
// we have form (2)
return new SqmParameterizedEntityType(
return new SqmEntityType(
(SqmParameter) ctx.entityTypeReference().parameter().accept( this ),
creationContext.getNodeBuilder()
);
}
else if ( ctx.entityTypeReference().path() != null ) {
final SqmNavigableReference<?> binding = (SqmNavigableReference) ctx.entityTypeReference().path().accept( this );
return binding.sqmAs( EntityValuedNavigable.class )
.getEntityDescriptor()
.getHierarchy()
.getDiscriminatorDescriptor()
.createSqmExpression( null, this );
// we have form (1)
return new SqmEntityType(
(SqmPath<?>) ctx.entityTypeReference().path().accept( this ),
creationContext.getNodeBuilder()
);
}
throw new ParsingException( "Could not interpret grammar context as 'entity type' expression : " + ctx.getText() );
@ -1320,10 +1317,12 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
if ( ctx.expression().size() != 2 ) {
throw new ParsingException( "Expecting 2 operands to the concat operator" );
}
//noinspection unchecked
return getFunctionTemplate( "concat" ).makeSqmFunctionExpression(
asList(
(SqmExpression) ctx.expression( 0 ).accept( this ),
(SqmExpression) ctx.expression( 1 ).accept( this )
(List) asList(
ctx.expression( 0 ).accept( this ),
ctx.expression( 1 ).accept( this )
),
resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
@ -1426,12 +1425,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public SqmCaseSimple visitSimpleCaseStatement(HqlParser.SimpleCaseStatementContext ctx) {
//noinspection unchecked
final SqmCaseSimple caseExpression = new SqmCaseSimple(
(SqmExpression) ctx.expression().accept( this ),
creationContext.getNodeBuilder()
);
for ( HqlParser.SimpleCaseWhenContext simpleCaseWhen : ctx.simpleCaseWhen() ) {
//noinspection unchecked
caseExpression.when(
(SqmExpression) simpleCaseWhen.expression( 0 ).accept( this ),
(SqmExpression) simpleCaseWhen.expression( 1 ).accept( this )
@ -1439,6 +1440,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
if ( ctx.caseOtherwise() != null ) {
//noinspection unchecked
caseExpression.otherwise( (SqmExpression) ctx.caseOtherwise().expression().accept( this ) );
}
@ -1450,6 +1452,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmCaseSearched<?> caseExpression = new SqmCaseSearched<>( creationContext.getNodeBuilder());
for ( HqlParser.SearchedCaseWhenContext whenFragment : ctx.searchedCaseWhen() ) {
//noinspection unchecked
caseExpression.when(
(SqmPredicate) whenFragment.predicate().accept( this ),
(SqmExpression) whenFragment.expression().accept( this )
@ -1457,6 +1460,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
if ( ctx.caseOtherwise() != null ) {
//noinspection unchecked
caseExpression.otherwise( (SqmExpression) ctx.caseOtherwise().expression().accept( this ) );
}
@ -1644,6 +1648,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
private SqmLiteral<Boolean> booleanLiteral(boolean value) {
final SqmExpressable expressionType = resolveExpressableTypeBasic( Boolean.class );
//noinspection unchecked
return new SqmLiteral<>( value, expressionType, creationContext.getQueryEngine().getCriteriaBuilder() );
}
@ -1662,7 +1667,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
private SqmLiteral<String> stringLiteral(String text) {
return new SqmLiteral<>(
text,
creationContext.getDomainModel().getTypeConfiguration().resolveStandardBasicType( StandardBasicTypes.STRING ),
resolveExpressableTypeBasic( String.class ),
creationContext.getNodeBuilder()
);
}
@ -1783,7 +1788,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
}
private <J> SqmExpressable<J> resolveExpressableTypeBasic(Class<J> javaType) {
private <J> BasicDomainType<J> resolveExpressableTypeBasic(Class<J> javaType) {
//noinspection unchecked
return creationContext.getDomainModel().getTypeConfiguration().standardBasicTypeForJavaType( javaType );
}
@ -1975,7 +1980,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate( ctx.trigFunctionName().getText() ).makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType<Double>) resolveExpressableTypeBasic( Double.class ),
resolveExpressableTypeBasic( Double.class ),
creationContext.getQueryEngine()
);
}
@ -2049,56 +2054,56 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
if (ctx.DAY()!=null) {
return new SqmExtractUnit<>(
"day",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.MONTH()!=null) {
return new SqmExtractUnit<>(
"month",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.YEAR()!=null) {
return new SqmExtractUnit<>(
"year",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.HOUR()!=null) {
return new SqmExtractUnit<>(
"hour",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.MINUTE()!=null) {
return new SqmExtractUnit<>(
"minute",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.SECOND()!=null) {
return new SqmExtractUnit<>(
"second",
(AllowableFunctionReturnType<Float>) resolveExpressableTypeBasic( Float.class ),
resolveExpressableTypeBasic( Float.class ),
nodeBuilder
);
}
if (ctx.WEEK()!=null) {
return new SqmExtractUnit<>(
"week",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.QUARTER()!=null) {
return new SqmExtractUnit<>(
"quarter",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
@ -2113,7 +2118,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
//TODO: need to go back to the dialect, it's called "microseconds" on some
return new SqmExtractUnit<>(
"microsecond",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
@ -2121,7 +2126,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
//TODO: need to go back to the dialect, it's called "milliseconds" on some
return new SqmExtractUnit<>(
"millisecond",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
@ -2134,14 +2139,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
if (ctx.TIMEZONE_HOUR()!=null) {
return new SqmExtractUnit<>(
"timezone_hour",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.TIMEZONE_MINUTE()!=null) {
return new SqmExtractUnit<>(
"timezone_minute",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
@ -2205,48 +2210,48 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
switch (text.toLowerCase()) {
case "string": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
resolveExpressableTypeBasic( String.class ),
nodeBuilder
);
}
case "integer": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
case "long": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Long>) resolveExpressableTypeBasic( Long.class ), nodeBuilder
resolveExpressableTypeBasic( Long.class ), nodeBuilder
);
}
case "float": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Float>) resolveExpressableTypeBasic( Float.class ),
resolveExpressableTypeBasic( Float.class ),
nodeBuilder
);
}
case "double": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Double>) resolveExpressableTypeBasic( Double.class ),
resolveExpressableTypeBasic( Double.class ),
nodeBuilder
);
}
case "time": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Time>) resolveExpressableTypeBasic( Time.class ),
resolveExpressableTypeBasic( Time.class ),
nodeBuilder
);
}
case "date": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Date>) resolveExpressableTypeBasic( Date.class ),
resolveExpressableTypeBasic( Date.class ),
nodeBuilder
);
}
case "timestamp": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Timestamp>) resolveExpressableTypeBasic( Timestamp.class ),
resolveExpressableTypeBasic( Timestamp.class ),
nodeBuilder
);
}
@ -2272,6 +2277,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
// todo (6.0) : why pass both the expression and its expression-type?
// can't we just pass the expression?
final SqmExpression expression = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("lower").makeSqmFunctionExpression(
expression,
(AllowableFunctionReturnType) expression.getNodeType(),
@ -2288,7 +2294,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("concat").makeSqmFunctionExpression(
arguments,
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
}
@ -2299,7 +2305,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("character_length").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@ -2311,7 +2317,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("locate").makeSqmFunctionExpression(
asList( pattern, string ),
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@ -2328,7 +2334,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
start == null
? asList( pattern, string )
: asList( pattern, string, start ),
( AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@ -2342,7 +2348,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("replace").makeSqmFunctionExpression(
asList( string, pattern, replacement ),
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
}
@ -2350,7 +2356,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public Object visitStrFunction(HqlParser.StrFunctionContext ctx) {
final SqmExpression<?> arg = (SqmExpression) ctx.expression().accept( this );
AllowableFunctionReturnType<String> type = (AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class );
AllowableFunctionReturnType<String> type = resolveExpressableTypeBasic( String.class );
return getFunctionTemplate("cast").makeSqmFunctionExpression(
asList( arg, new SqmCastTarget<>( type, creationContext.getNodeBuilder() ) ),
type,
@ -2401,7 +2407,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("avg").makeSqmFunctionExpression(
argument,
(AllowableFunctionReturnType<Double>) resolveExpressableTypeBasic( Double.class ),
resolveExpressableTypeBasic( Double.class ),
creationContext.getQueryEngine()
);
}
@ -2416,7 +2422,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("count").makeSqmFunctionExpression(
argument,
(AllowableFunctionReturnType<Long>) resolveExpressableTypeBasic( Long.class ),
resolveExpressableTypeBasic( Long.class ),
creationContext.getQueryEngine()
);
}
@ -2429,9 +2435,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
? null
: (SqmExpression) ctx.substringFunctionLengthArgument().accept( this );
//noinspection unchecked
return getFunctionTemplate("substring").makeSqmFunctionExpression(
length==null ? asList( source, start ) : asList( source, start, length ),
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
@ -2448,7 +2455,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
visitTrimCharacter( ctx.trimCharacter() ),
source
),
(AllowableFunctionReturnType) resolveExpressableTypeBasic( String.class ),
resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
}
@ -2727,7 +2734,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public SqmPath<?> visitTreatedNavigablePath(HqlParser.TreatedNavigablePathContext ctx) {
final SqmPath<?> sqmPath = consumeNavigableContainerReference( ctx.path() );
final SqmPath<?> sqmPath = consumeManagedTypeReference( ctx.path() );
final String treatTargetName = ctx.dotIdentifierSequence().getText();
final EntityDomainType<?> treatTarget = getCreationContext().getDomainModel().entity( treatTargetName );
@ -2756,18 +2763,27 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public SqmPath<?> visitCollectionElementNavigablePath(HqlParser.CollectionElementNavigablePathContext ctx) {
final SqmPath<?> sqmPath = consumeNavigableContainerReference( ctx.path() );
final PluralValuedNavigable pluralValuedNavigable = sqmPath.sqmAs( PluralValuedNavigable.class );
final SqmPath<?> sqmPath = consumeManagedTypeReference( ctx.path() );
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
if ( !(referencedPathSource instanceof PluralPersistentAttribute ) ) {
throw new PathException(
"Illegal attempt to treat non-plural path as a plural path : " + sqmPath.getNavigablePath()
);
}
final PluralPersistentAttribute attribute = (PluralPersistentAttribute) referencedPathSource;
if ( getCreationOptions().useStrictJpaCompliance() ) {
if ( pluralValuedNavigable.getCollectionDescriptor().getCollectionClassification() != CollectionClassification.MAP ) {
if ( attribute.getCollectionClassification() != CollectionClassification.MAP ) {
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.VALUE_FUNCTION_ON_NON_MAP );
}
}
SqmPath result = pluralValuedNavigable.getCollectionDescriptor()
.getElementDescriptor()
.createSqmExpression( sqmPath, this );
SqmPath result = attribute.getElementPathSource().createSqmPath(
sqmPath,
this
);
if ( ctx.pathContinuation() != null ) {
result = consumeDomainPath( ctx.path() );
@ -2780,9 +2796,18 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public SqmPath visitMapKeyNavigablePath(HqlParser.MapKeyNavigablePathContext ctx) {
final SqmPath<?> sqmPath = consumeDomainPath( ctx.path() );
final SqmPath<?> result = sqmPath.sqmAs( PersistentCollectionDescriptor.class )
.getIndexDescriptor()
.createSqmExpression( sqmPath, this );
final SqmPathSource<?> referencedPathSource = sqmPath.getReferencedPathSource();
if ( ! (referencedPathSource instanceof MapPersistentAttribute ) ) {
throw new PathException(
"SqmPath#referencedPathSource [" + sqmPath + "] does not refer"
);
}
final MapPersistentAttribute attribute = (MapPersistentAttribute) referencedPathSource;
//noinspection unchecked
final SqmPath result = attribute.getKeyPathSource().createSqmPath( sqmPath, this );
if ( ctx.pathContinuation() != null ) {
return consumeDomainPath( ctx.path() );
@ -2815,33 +2840,33 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new SemanticException( "Expecting domain-model path, but found : " + consumedPart );
}
private SqmPath consumeNavigableContainerReference(HqlParser.PathContext parserPath) {
private SqmPath consumeManagedTypeReference(HqlParser.PathContext parserPath) {
final SqmPath sqmPath = consumeDomainPath( parserPath );
final Navigable navigable = sqmPath.getReferencedPathSource();
if ( navigable instanceof NavigableContainer ) {
final SqmPathSource pathSource = sqmPath.getReferencedPathSource();
try {
// use the `#sqmAs` call to validate the path is a ManagedType
pathSource.sqmAs( ManagedDomainType.class );
return sqmPath;
}
throw new SemanticException( "Expecting NavigableContainer-valued path, but found : " + navigable );
catch (Exception e) {
throw new SemanticException( "Expecting ManagedType valued path [" + sqmPath.getNavigablePath() + "], but found : " + pathSource.getSqmPathType() );
}
}
private SqmPath consumePluralAttributeReference(HqlParser.PathContext parserPath) {
final SqmPath sqmPath = consumeDomainPath( parserPath );
final Navigable navigable = sqmPath.getReferencedPathSource();
try {
sqmPath.getReferencedPathSource().as( PluralValuedNavigable.class );
if ( sqmPath.getReferencedPathSource() instanceof PluralPersistentAttribute ) {
return sqmPath;
}
catch (Exception e) {
throw new SemanticException( "Expecting PluralAttribute-valued path, but found : " + navigable );
}
throw new SemanticException( "Expecting plural attribute valued path [" + sqmPath.getNavigablePath() + "], but found : " + sqmPath.getReferencedPathSource().getSqmPathType() );
}
private interface TreatHandler {
void addDowncast(SqmFrom sqmFrom, IdentifiableTypeDescriptor downcastTarget);
void addDowncast(SqmFrom sqmFrom, IdentifiableDomainType downcastTarget);
}
private static class TreatHandlerNormal implements TreatHandler {
@ -2858,7 +2883,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public void addDowncast(
SqmFrom sqmFrom,
IdentifiableTypeDescriptor downcastTarget) {
IdentifiableDomainType downcastTarget) {
( (MutableUsageDetails) sqmFrom.getUsageDetails() ).addDownCast( false, downcastTarget, downcastLocation );
}
}
@ -2867,7 +2892,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public void addDowncast(
SqmFrom sqmFrom,
IdentifiableTypeDescriptor downcastTarget) {
IdentifiableDomainType downcastTarget) {
( (MutableUsageDetails) sqmFrom.getUsageDetails() ).addDownCast( true, downcastTarget, DowncastLocation.FROM );
}
}

View File

@ -0,0 +1,24 @@
/*
* 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 org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.query.named.spi.NameableQuery;
import org.hibernate.query.named.spi.NamedHqlQueryMemento;
import org.hibernate.query.spi.ParameterMetadataImplementor;
import org.hibernate.query.spi.QueryImplementor;
/**
* @author Steve Ebersole
*/
public interface HqlQueryImplementor<R> extends QueryImplementor<R>, NameableQuery {
@Override
NamedHqlQueryMemento toMemento(String name, SessionFactoryImplementor factory);
@Override
ParameterMetadataImplementor getParameterMetadata();
}

View File

@ -0,0 +1,14 @@
/*
* 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 defining the representations of named query related objects in
* terms of the run-time environment
*
* @see org.hibernate.query.spi.NamedQueryRepository
*/
package org.hibernate.query.named;

View File

@ -0,0 +1,172 @@
/*
* 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.named.spi;
import java.util.List;
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.procedure.internal.Util;
import org.hibernate.query.spi.QueryImplementor;
/**
* @author Steve Ebersole
*/
public abstract class AbstractNamedQueryMemento implements NamedQueryMemento {
private final String name;
private final List<ParameterMemento> parameterMementos;
private final Boolean cacheable;
private final String cacheRegion;
private final CacheMode cacheMode;
private final FlushMode flushMode;
private final Boolean readOnly;
private final LockOptions lockOptions;
private final Integer timeout;
private final Integer fetchSize;
private final String comment;
private final Map<String, Object> hints;
public AbstractNamedQueryMemento(
String name,
List<ParameterMemento> parameterMementos,
Boolean cacheable,
String cacheRegion,
CacheMode cacheMode,
FlushMode flushMode,
Boolean readOnly,
LockOptions lockOptions,
Integer timeout,
Integer fetchSize,
String comment,
Map<String, Object> hints) {
this.name = name;
this.parameterMementos = parameterMementos;
this.cacheable = cacheable;
this.cacheRegion = cacheRegion;
this.cacheMode = cacheMode;
this.flushMode = flushMode;
this.readOnly = readOnly;
this.lockOptions = lockOptions;
this.timeout = timeout;
this.fetchSize = fetchSize;
this.comment = comment;
this.hints = hints;
}
@Override
public String getName() {
return name;
}
public List<ParameterMemento> getParameterMementos() {
return parameterMementos;
}
@Override
public Boolean getCacheable() {
return cacheable;
}
@Override
public String getCacheRegion() {
return cacheRegion;
}
@Override
public CacheMode getCacheMode() {
return cacheMode;
}
@Override
public FlushMode getFlushMode() {
return flushMode;
}
@Override
public Boolean getReadOnly() {
return readOnly;
}
@Override
public LockOptions getLockOptions() {
return lockOptions;
}
@Override
public Integer getTimeout() {
return timeout;
}
@Override
public Integer getFetchSize() {
return fetchSize;
}
@Override
public String getComment() {
return comment;
}
@Override
public Map<String, Object> getHints() {
return hints;
}
protected Map<String, Object> getHintsCopy() {
return Util.copy( hints );
}
protected void applyBaseOptions(QueryImplementor query, SharedSessionContractImplementor session) {
getHints().forEach( query::setHint );
if ( cacheable != null ) {
query.setCacheable( cacheable );
}
if ( cacheRegion != null ) {
query.setCacheRegion( cacheRegion );
}
if ( cacheMode != null ) {
query.setCacheMode( cacheMode );
}
if ( flushMode != null ) {
query.setHibernateFlushMode( flushMode );
}
if ( readOnly != null ) {
query.setReadOnly( readOnly );
}
if ( lockOptions != null ) {
query.setLockOptions( lockOptions );
}
if ( timeout != null ) {
query.setTimeout( timeout );
}
if ( fetchSize != null ) {
query.setFetchSize( fetchSize );
}
if ( comment != null ) {
query.setComment( comment );
}
}
}

View File

@ -0,0 +1,222 @@
/*
* 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.named.spi;
import java.util.Map;
import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.jpa.QueryHints;
import org.hibernate.jpa.internal.util.FlushModeTypeHelper;
import org.hibernate.jpa.internal.util.LockModeTypeHelper;
/**
* @author Steve Ebersole
*/
public class Helper {
public static abstract class NamedQueryDescriptorBuilder {
private final String name;
private final Map<String, Object> hints;
private Boolean cacheable;
private String cacheRegion;
private CacheMode cacheMode;
private FlushMode flushMode;
private Boolean readOnly;
private LockOptions lockOptions;
private Integer timeout;
private Integer fetchSize;
private String comment;
public NamedQueryDescriptorBuilder(
String name,
Map<String, Object> hints,
SessionFactoryImplementor sessionFactory) {
this.name = name;
this.hints = hints;
cacheable = isCacheable( hints, sessionFactory );
cacheRegion = cacheable ? determineCacheRegion( hints, sessionFactory ) : null;
cacheMode = cacheable ? determineCacheMode( hints, sessionFactory ) : null;
flushMode = determineFlushMode( hints, sessionFactory );
readOnly = ConfigurationHelper.getBoolean( QueryHints.HINT_READONLY, hints, false );
lockOptions = determineLockOptions( hints, sessionFactory );
timeout = determineTimeout( hints, sessionFactory );
}
public String getName() {
return name;
}
public Map<String, Object> getHints() {
return hints;
}
public Boolean getCacheable() {
return cacheable;
}
public void setCacheable(Boolean cacheable) {
this.cacheable = cacheable;
}
public String getCacheRegion() {
return cacheRegion;
}
public void setCacheRegion(String cacheRegion) {
this.cacheRegion = cacheRegion;
}
public CacheMode getCacheMode() {
return cacheMode;
}
public void setCacheMode(CacheMode cacheMode) {
this.cacheMode = cacheMode;
}
public FlushMode getFlushMode() {
return flushMode;
}
public void setFlushMode(FlushMode flushMode) {
this.flushMode = flushMode;
}
public Boolean getReadOnly() {
return readOnly;
}
public void setReadOnly(Boolean readOnly) {
this.readOnly = readOnly;
}
public LockOptions getLockOptions() {
return lockOptions;
}
public void setLockOptions(LockOptions lockOptions) {
this.lockOptions = lockOptions;
}
public Integer getTimeout() {
return timeout;
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
public Integer getFetchSize() {
return fetchSize;
}
public void setFetchSize(Integer fetchSize) {
this.fetchSize = fetchSize;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
private static boolean isCacheable(Map<String, Object> hints, SessionFactoryImplementor sessionFactory) {
return sessionFactory.getSessionFactoryOptions().isQueryCacheEnabled()
&& ConfigurationHelper.getBoolean( QueryHints.HINT_CACHEABLE, hints, false );
}
private static String determineCacheRegion(Map<String, Object> hints, SessionFactoryImplementor sessionFactory) {
assert sessionFactory.getSessionFactoryOptions().isQueryCacheEnabled();
return ConfigurationHelper.getString( QueryHints.HINT_CACHE_REGION, hints, null );
}
private static CacheMode determineCacheMode(Map<String, Object> hints, SessionFactoryImplementor sessionFactory) {
assert sessionFactory.getSessionFactoryOptions().isQueryCacheEnabled();
final Object setting = hints.get( QueryHints.HINT_CACHE_MODE );
if ( setting != null ) {
if ( CacheMode.class.isInstance( setting ) ) {
return (CacheMode) setting;
}
final CacheMode cacheMode = CacheMode.interpretExternalSetting( setting.toString() );
if ( cacheMode != null ) {
return cacheMode;
}
}
return CacheMode.NORMAL;
}
private static FlushMode determineFlushMode(Map<String, Object> hints, SessionFactoryImplementor sessionFactory) {
final Object setting = hints.get( QueryHints.HINT_FLUSH_MODE );
if ( setting != null ) {
if ( FlushMode.class.isInstance( setting ) ) {
return (FlushMode) setting;
}
if ( FlushModeType.class.isInstance( setting ) ) {
return FlushModeTypeHelper.getFlushMode( FlushModeType.class.cast( setting ) );
}
final FlushMode mode = FlushMode.interpretExternalSetting( setting.toString() );
if ( mode != null ) {
return mode;
}
}
return FlushMode.AUTO;
}
private static LockOptions determineLockOptions(Map<String, Object> hints, SessionFactoryImplementor sessionFactory) {
final Object lockModeSetting = hints.get( QueryHints.HINT_NATIVE_LOCKMODE );
final LockMode lockMode;
if ( lockModeSetting == null ) {
lockMode = LockMode.NONE;
}
else if ( LockMode.class.isInstance( lockModeSetting ) ) {
lockMode = LockMode.class.cast( lockModeSetting );
}
else if ( LockModeType.class.isInstance( lockModeSetting ) ) {
lockMode = LockModeTypeHelper.getLockMode( LockModeType.class.cast( lockModeSetting ) );
}
else {
lockMode = LockMode.fromExternalForm( lockModeSetting.toString() );
}
if ( lockMode == LockMode.NONE ) {
return LockOptions.NONE;
}
else {
return new LockOptions( lockMode );
}
}
private static Integer determineTimeout(Map<String, Object> hints, SessionFactoryImplementor sessionFactory) {
return null;
}
}

View File

@ -0,0 +1,19 @@
/*
* 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.named.spi;
import org.hibernate.engine.spi.SessionFactoryImplementor;
/**
* Contract for Query impls that can be converted to named queries and
* stored in the {@link org.hibernate.query.spi.NamedQueryRepository}
*
* @author Steve Ebersole
*/
public interface NameableQuery {
NamedQueryMemento toMemento(String name, SessionFactoryImplementor factory);
}

View File

@ -0,0 +1,31 @@
/*
* 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.named.spi;
import java.util.Set;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.procedure.spi.ProcedureCallImplementor;
/**
* @author Steve Ebersole
*/
public interface NamedCallableQueryMemento extends NamedQueryMemento {
String getCallableName();
Set<String> getQuerySpaces();
Class[] getResultClasses();
String[] getResultSetMappingNames();
@Override
NamedCallableQueryMemento makeCopy(String name);
@Override
<T> ProcedureCallImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
}

View File

@ -0,0 +1,28 @@
/*
* 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.named.spi;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.hql.spi.HqlQueryImplementor;
/**
* @author Steve Ebersole
*/
public interface NamedHqlQueryMemento extends NamedQueryMemento {
String getHqlString();
@Override
default String getQueryString() {
return getHqlString();
}
@Override
NamedHqlQueryMemento makeCopy(String name);
@Override
<T> HqlQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
}

View File

@ -0,0 +1,31 @@
/*
* 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.named.spi;
import java.util.Set;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.spi.NativeQueryImplementor;
/**
* Descriptor for a named native query in the run-time environment
*
* @author Steve Ebersole
*/
public interface NamedNativeQueryMemento extends NamedQueryMemento {
String getSqlString();
String getResultSetMappingName();
Set<String> getQuerySpaces();
@Override
NamedNativeQueryMemento makeCopy(String name);
@Override
<T> NativeQueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
}

View File

@ -0,0 +1,51 @@
/*
* 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.named.spi;
import java.util.List;
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.spi.QueryImplementor;
/**
* @author Steve Ebersole
*/
public interface NamedQueryMemento {
String getName();
String getQueryString();
List<ParameterMemento> getParameterMementos();
Boolean getCacheable();
String getCacheRegion();
CacheMode getCacheMode();
FlushMode getFlushMode();
Boolean getReadOnly();
LockOptions getLockOptions();
Integer getTimeout();
Integer getFetchSize();
String getComment();
Map<String,Object> getHints();
NamedQueryMemento makeCopy(String name);
<T> QueryImplementor<T> toQuery(SharedSessionContractImplementor session, Class<T> resultType);
}

View File

@ -0,0 +1,17 @@
/*
* 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.named.spi;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.query.QueryParameter;
/**
* @author Steve Ebersole
*/
public interface ParameterMemento {
QueryParameter toQueryParameter(SharedSessionContractImplementor session);
}

View File

@ -0,0 +1,16 @@
/*
* 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.named.spi;
/**
* @author Steve Ebersole
*/
public interface RowReaderMemento {
Class[] getResultClasses();
String[] getResultMappingNames();
}

View File

@ -0,0 +1,39 @@
/*
* 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.spi;
import java.util.Set;
import java.util.function.Predicate;
import javax.persistence.Parameter;
import org.hibernate.query.ParameterMetadata;
/**
* @author Steve Ebersole
*/
public interface ParameterMetadataImplementor extends ParameterMetadata {
@Override
<T> QueryParameterImplementor<T> getQueryParameter(String name);
@Override
<T> QueryParameterImplementor<T> getQueryParameter(int positionLabel);
@Override
<T> QueryParameterImplementor<T> resolve(Parameter<T> param);
@Override
Set<? extends QueryParameterImplementor<?>> getRegistrations();
@FunctionalInterface
interface ParameterCollector {
void collect(QueryParameterImplementor<?> queryParameter);
}
void collectAllParameters(ParameterCollector collector);
boolean hasAnyMatching(Predicate<QueryParameterImplementor<?>> filter);
}

View File

@ -0,0 +1,19 @@
/*
* 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.spi;
import org.hibernate.query.QueryParameter;
import org.hibernate.query.named.spi.ParameterMemento;
/**
* @author Steve Ebersole
*/
public interface QueryParameterImplementor<T> extends QueryParameter<T> {
void disallowMultiValuedBinding();
ParameterMemento toMemento();
}

View File

@ -9,6 +9,7 @@ package org.hibernate.query.sqm;
import javax.persistence.metamodel.Bindable;
import org.hibernate.metamodel.model.domain.DomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.query.sqm.tree.domain.SqmPath;
@ -40,4 +41,6 @@ public interface SqmPathSource<J> extends SqmExpressable<J>, Bindable<J> {
* Create an SQM path for this source relative to the given left-hand side
*/
SqmPath<J> createSqmPath(SqmPath<?> lhs, SqmCreationState creationState);
<X extends DomainType> X sqmAs(Class<X> type);
}

View File

@ -32,7 +32,7 @@ import org.hibernate.query.sqm.tree.expression.SqmExpression;
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.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple;
@ -429,7 +429,7 @@ public class BaseSemanticQueryWalker<T> implements SemanticQueryWalker<T> {
}
@Override
public T visitParameterizedEntityTypeExpression(SqmParameterizedEntityType expression) {
public T visitParameterizedEntityTypeExpression(SqmEntityType expression) {
return (T) expression;
}

View File

@ -31,7 +31,7 @@ import org.hibernate.query.sqm.tree.expression.SqmExpression;
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.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple;
@ -177,7 +177,7 @@ public interface SemanticQueryWalker<T> {
T visitEntityTypeLiteralExpression(SqmLiteralEntityType<?> expression);
T visitParameterizedEntityTypeExpression(SqmParameterizedEntityType<?> expression);
T visitParameterizedEntityTypeExpression(SqmEntityType<?> expression);
T visitUnaryOperationExpression(SqmUnaryOperation<?> expression);

View File

@ -34,7 +34,7 @@ import org.hibernate.query.sqm.tree.expression.SqmExpression;
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.SqmParameterizedEntityType;
import org.hibernate.query.sqm.tree.expression.SqmEntityType;
import org.hibernate.query.sqm.tree.expression.SqmPositionalParameter;
import org.hibernate.query.sqm.tree.expression.SqmRestrictedSubQueryExpression;
import org.hibernate.query.sqm.tree.expression.SqmTuple;
@ -558,7 +558,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
}
@Override
public Object visitParameterizedEntityTypeExpression(SqmParameterizedEntityType expression) {
public Object visitParameterizedEntityTypeExpression(SqmEntityType expression) {
return null;
}

View File

@ -10,7 +10,7 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
/**
* @author Steve Ebersole

View File

@ -9,7 +9,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;

View File

@ -20,7 +20,7 @@ import org.hibernate.query.criteria.JpaCollectionJoin;
import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -124,11 +124,11 @@ public class SqmBagJoin<O, E> extends AbstractSqmPluralJoin<O,Collection<E>, E>
@Override
public <S extends E> SqmTreatedBagJoin<O, E, S> treatAs(Class<S> treatAsType) {
return (SqmTreatedBagJoin<O, E, S>) treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
return treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends E> SqmTreatedBagJoin<O,E,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedBagJoin( this, treatTarget, null );
}

View File

@ -7,7 +7,7 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SqmPathSource;

View File

@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;

View File

@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;

View File

@ -10,7 +10,7 @@ import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;

View File

@ -21,7 +21,7 @@ import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaListJoin;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -101,11 +101,11 @@ public class SqmListJoin<O,E> extends AbstractSqmPluralJoin<O,List<E>, E> implem
@Override
public <S extends E> SqmTreatedListJoin<O,E,S> treatAs(Class<S> treatAsType) {
return (SqmTreatedListJoin<O,E,S>) treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
return treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends E> SqmTreatedListJoin<O,E,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedListJoin( this, treatTarget, null );
}

View File

@ -20,7 +20,7 @@ import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaMapJoin;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
@ -169,17 +169,18 @@ public class SqmMapJoin<O,K,V> extends AbstractSqmPluralJoin<O,Map<K,V>,V> imple
@Override
public <S extends V> SqmTreatedMapJoin<O,K,V,S> treatAs(Class<S> treatJavaType) throws PathException {
return (SqmTreatedMapJoin<O,K,V,S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends V> SqmTreatedPath<V, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends V> SqmTreatedMapJoin<O,K,V,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedMapJoin( this, treatTarget, null );
}
@Override
public SqmAttributeJoin makeCopy(SqmCreationProcessingState creationProcessingState) {
//noinspection unchecked
return new SqmMapJoin(
creationProcessingState.getPathRegistry().findFromByPath( getLhs().getNavigablePath() ),
getReferencedPathSource(),

View File

@ -9,7 +9,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.ParsingException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SqmExpressable;

View File

@ -12,7 +12,7 @@ import org.hibernate.metamodel.model.domain.MapPersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.persister.collection.CollectionPropertyNames;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;

View File

@ -20,7 +20,7 @@ import org.hibernate.query.criteria.JpaExpression;
import org.hibernate.query.criteria.JpaPredicate;
import org.hibernate.query.criteria.JpaSetJoin;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -93,11 +93,11 @@ public class SqmSetJoin<O, E>
@Override
public <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(Class<S> treatAsType) {
return (SqmTreatedSetJoin<O,E,S>) treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
return treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
return new SqmTreatedSetJoin<>( this, treatTarget, null );
}

View File

@ -10,7 +10,7 @@ import java.util.Locale;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -44,11 +44,11 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(Class<S> treatJavaType) throws PathException {
return (SqmTreatedSingularJoin<O,T,S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends T> SqmTreatedPath<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedSingularJoin( this, treatTarget, null );
}
@ -65,6 +65,7 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
@Override
public SqmAttributeJoin makeCopy(SqmCreationProcessingState creationProcessingState) {
//noinspection unchecked
return new SqmSingularJoin(
creationProcessingState.getPathRegistry().findFromByPath( getLhs().getNavigablePath() ),
getReferencedPathSource(),

View File

@ -7,7 +7,7 @@
package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;

View File

@ -17,6 +17,7 @@ import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.produce.SqmTreeCreationLogger;
import org.hibernate.query.sqm.tree.jpa.AbstractJpaSelection;
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.query.internal.QueryHelper.highestPrecedenceType;
@ -52,43 +53,49 @@ public abstract class AbstractSqmExpression<T> extends AbstractJpaSelection<T> i
newType
);
//noinspection unchecked
setExpressableType( (SqmExpressable) highestPrecedenceType( newType, getNodeType() ) );
setExpressableType( highestPrecedenceType( newType, getNodeType() ) );
}
@Override
public SqmExpression<Long> asLong() {
return castAs( StandardSpiBasicTypes.LONG );
//noinspection unchecked
return castAs( StandardBasicTypes.LONG );
}
@Override
public SqmExpression<Integer> asInteger() {
return castAs( StandardSpiBasicTypes.INTEGER );
//noinspection unchecked
return castAs( StandardBasicTypes.INTEGER );
}
@Override
public SqmExpression<Float> asFloat() {
return castAs( StandardSpiBasicTypes.FLOAT );
//noinspection unchecked
return castAs( StandardBasicTypes.FLOAT );
}
@Override
public SqmExpression<Double> asDouble() {
return castAs( StandardSpiBasicTypes.DOUBLE );
//noinspection unchecked
return castAs( StandardBasicTypes.DOUBLE );
}
@Override
public SqmExpression<BigDecimal> asBigDecimal() {
return castAs( StandardSpiBasicTypes.BIG_DECIMAL );
//noinspection unchecked
return castAs( StandardBasicTypes.BIG_DECIMAL );
}
@Override
public SqmExpression<BigInteger> asBigInteger() {
return castAs( StandardSpiBasicTypes.BIG_INTEGER );
//noinspection unchecked
return castAs( StandardBasicTypes.BIG_INTEGER );
}
@Override
public SqmExpression<String> asString() {
return castAs( StandardSpiBasicTypes.STRING );
//noinspection unchecked
return castAs( StandardBasicTypes.STRING );
}
@Override

View File

@ -15,10 +15,6 @@ import java.time.LocalTime;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.type.descriptor.java.internal.JdbcDateJavaDescriptor;
import org.hibernate.type.descriptor.java.internal.JdbcTimeJavaDescriptor;
import org.hibernate.type.descriptor.java.internal.JdbcTimestampJavaDescriptor;
import org.hibernate.type.spi.StandardSpiBasicTypes;
/**
* @author Steve Ebersole

View File

@ -29,7 +29,7 @@ public class SqmCaseSearched<R> extends AbstractSqmExpression<R> implements JpaS
this( null, nodeBuilder );
}
public SqmCaseSearched(BasicValuedExpressableType<R> inherentType, NodeBuilder nodeBuilder) {
public SqmCaseSearched(SqmExpressable<R> inherentType, NodeBuilder nodeBuilder) {
super( inherentType, nodeBuilder );
}

View File

@ -6,10 +6,11 @@
*/
package org.hibernate.query.sqm.tree.expression;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.sql.ast.produce.metamodel.spi.EntityValuedExpressableType;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.DomainResultProducer;
@ -19,18 +20,18 @@ import org.hibernate.sql.results.spi.DomainResultProducer;
*
* @author Steve Ebersole
*/
public class SqmParameterizedEntityType<T> extends AbstractSqmExpression<T> implements DomainResultProducer {
private final SqmParameter parameterExpression;
public class SqmEntityType<T> extends AbstractSqmExpression<T> implements DomainResultProducer {
private final SqmExpression discriminatorSource;
public SqmParameterizedEntityType(SqmParameter<T> parameterExpression, NodeBuilder nodeBuilder) {
public SqmEntityType(SqmParameter<T> parameterExpression, NodeBuilder nodeBuilder) {
super( parameterExpression.getAnticipatedType(), nodeBuilder );
this.parameterExpression = parameterExpression;
this.discriminatorSource = parameterExpression;
}
@Override
public EntityValuedExpressableType<T> getNodeType() {
public SqmEntityType(SqmPath<T> entityValuedPath, NodeBuilder nodeBuilder) {
//noinspection unchecked
return (EntityValuedExpressableType<T>) parameterExpression.getNodeType();
super( entityValuedPath.getReferencedPathSource().sqmAs( EntityDomainType.class ), nodeBuilder );
this.discriminatorSource = entityValuedPath;
}
@Override
@ -38,7 +39,7 @@ public class SqmParameterizedEntityType<T> extends AbstractSqmExpression<T> impl
setExpressableType( type );
//noinspection unchecked
parameterExpression.applyInferableType( type );
discriminatorSource.applyInferableType( type );
}
@Override
@ -46,11 +47,6 @@ public class SqmParameterizedEntityType<T> extends AbstractSqmExpression<T> impl
return walker.visitParameterizedEntityTypeExpression( this );
}
@Override
public String asLoggableText() {
return "TYPE(" + parameterExpression.asLoggableText() + ")";
}
@Override
public DomainResult createDomainResult(
String resultVariable,

View File

@ -7,12 +7,13 @@
package org.hibernate.query.sqm.tree.from;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.SqmJoinType;
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedCrossJoin;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import static org.hibernate.query.sqm.produce.SqmCreationHelper.buildRootNavigablePath;
@ -82,7 +83,11 @@ public class SqmCrossJoin<T> extends AbstractSqmFrom<T,T> implements SqmJoin<T,T
@Override
public <S extends T> SqmTreatedCrossJoin<T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> treatTarget = nodeBuilder().getDomainModel().entity( treatJavaType );
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends T> SqmTreatedCrossJoin<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
return new SqmTreatedCrossJoin<>( this, null, treatTarget );
}
}

View File

@ -7,7 +7,7 @@
package org.hibernate.query.sqm.tree.from;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.produce.SqmCreationHelper;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -83,7 +83,10 @@ public class SqmEntityJoin<T> extends AbstractSqmJoin<T,T> implements SqmQualifi
@Override
public <S extends T> SqmTreatedEntityJoin<T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> treatTarget = nodeBuilder().getDomainModel().entity( treatJavaType );
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends T> SqmTreatedEntityJoin<T,S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
return new SqmTreatedEntityJoin<>( this, treatTarget, null, getSqmJoinType() );
}
}

View File

@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.from;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.criteria.JpaRoot;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;

View File

@ -0,0 +1,25 @@
/*
* 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.sql.results;
import org.hibernate.HibernateException;
/**
* Base for problems creating {@link org.hibernate.sql.results.spi.DomainResult}
* instances
*
* @author Steve Ebersole
*/
public class DomainResultCreationException extends HibernateException {
public DomainResultCreationException(String message) {
super( message );
}
public DomainResultCreationException(String message, Throwable cause) {
super( message, cause );
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.sql.results;
import org.jboss.logging.BasicLogger;
import org.jboss.logging.Logger;
import org.jboss.logging.annotations.MessageLogger;
import org.jboss.logging.annotations.ValidIdRange;
/**
* @author Steve Ebersole
*/
@MessageLogger( projectCode = "HHH" )
@ValidIdRange( min = 90005001, max = 90005100 )
public interface SqlResultsLogger extends BasicLogger {
String LOGGER_NAME = "org.hibernate.orm.sql.results";
/**
* Static access to the logging instance
*/
SqlResultsLogger INSTANCE = Logger.getMessageLogger(
SqlResultsLogger.class,
LOGGER_NAME
);
// todo (6.0) : make sure sql result processing classes use this logger
boolean TRACE_ENABLED = INSTANCE.isTraceEnabled();
boolean DEBUG_ENABLED = INSTANCE.isDebugEnabled();
boolean INFO_ENABLED = INSTANCE.isInfoEnabled();
}

View File

@ -0,0 +1,11 @@
/*
* 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 for processing JDBC ResultSets into domain results
*/
package org.hibernate.sql.results;

View File

@ -0,0 +1,13 @@
/*
* 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.sql.results.spi;
/**
* @author Steve Ebersole
*/
public interface AssemblerCreationState {
}

View File

@ -0,0 +1,48 @@
/*
* 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.sql.results.spi;
import java.util.function.Consumer;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
/**
* Represents a result value in the domain query results. Acts as the
* producer for the {@link DomainResultAssembler} for this result as well
* as any {@link Initializer} instances needed
* <p/>
* Not the same as a result column in the JDBC ResultSet! This contract
* represents an individual domain-model-level query result. A QueryResult
* will usually consume multiple JDBC result columns.
* <p/>
* QueryResult is distinctly different from a {@link Fetch} and so modeled as
* completely separate hierarchy.
*
* @see ScalarResult
* @see DynamicInstantiationResult
* @see EntityResult
* @see CollectionResult
* @see CompositeResult
* @see Fetch
*
* @author Steve Ebersole
*/
public interface DomainResult extends ResultSetMappingNode {
/**
* The result-variable (alias) associated with this result.
*/
String getResultVariable();
JavaTypeDescriptor getJavaTypeDescriptor();
/**
* Create an assembler (and any initializers) for this result.
*/
DomainResultAssembler createResultAssembler(
Consumer<Initializer> initializerCollector,
AssemblerCreationState creationState);
}

View File

@ -0,0 +1,18 @@
/*
* 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.sql.results.spi;
/**
* Responsible for "assembling" a result for inclusion in the domain query
* result. "Assembling" the result basically means building the result object
* (whatever that means for a specific result type) and returning it for
* injection into the result "row" currently being processed
*
* @author Steve Ebersole
*/
public interface DomainResultAssembler {
}

View File

@ -0,0 +1,13 @@
/*
* 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.sql.results.spi;
/**
* @author Steve Ebersole
*/
public interface DomainResultCreationState {
}

View File

@ -0,0 +1,38 @@
/*
* 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.sql.results.spi;
/**
* Represents something that can produce a {@link DomainResult}
* instances which can be used as selection items and
* dynamic-instantiation args in a domain query.
*
* @author Steve Ebersole
*/
public interface DomainResultProducer {
/**
* Produce the domain query
*/
DomainResult createDomainResult(
String resultVariable,
DomainResultCreationState creationState);
/**
* Used when this producer is a selection in a sub-query. The
* DomainResult is only needed for root query of a SELECT statement.
*
* This default impl assumes this producer is a true (Sql)Expression
*/
default void applySqlSelections(DomainResultCreationState creationState) {
// // this form works for basic-valued nodes
// creationState.getSqlExpressionResolver().resolveSqlSelection(
// (Expression) this,
// ( (Expression) this ).getType().getJavaTypeDescriptor(),
// creationState.getSqlAstCreationState().getCreationContext().getDomainModel().getTypeConfiguration()
// );
}
}

View File

@ -0,0 +1,17 @@
/*
* 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.sql.results.spi;
/**
* Defines a multi-step process for initializing entity, collection and
* composite state. Each step is performed on each initializer
* before starting the next step.
*
* @author Steve Ebersole
*/
public interface Initializer {
}

View File

@ -0,0 +1,33 @@
/*
* 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.sql.results.spi;
import org.hibernate.query.NavigablePath;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* Marker for all object types that can be part of a ResultSetMapping.
*
* Both {@link DomainResult} and {@link Fetch} are ResultSetMappingNode sub-types.
*
* @author Steve Ebersole
*/
public interface ResultSetMappingNode {
// todo (6.0) : result variable (selection alias)? - even fetches can have alias
JavaTypeDescriptor getJavaTypeDescriptor();
/**
* The NavigablePath for this node (if one!). Certain nodes will not
* have a NavigablePath, namely those not associated with a Navigable
*/
default NavigablePath getNavigablePath() {
// by default these nodes would not have a path. those that do explicitly
// override this already to return it
return null;
}
}