6 - SQM based on JPA type system

This commit is contained in:
Steve Ebersole 2019-05-23 13:29:09 -05:00 committed by Andrea Boriero
parent e8f22dc2ef
commit 4c058d8e9c
42 changed files with 555 additions and 205 deletions

View File

@ -14,12 +14,12 @@ import org.hibernate.metamodel.model.domain.JpaMetamodel;
/**
* @author Steve Ebersole
*
* @deprecated (since 6.0) Access to JPA's type system and Hibernate's type
* system has been separated into {@link JpaMetamodel}
* and {@link org.hibernate.metamodel.spi.RuntimeModel} respectively.
* @deprecated (since 6.0) Prefer {@link JpaMetamodel}
*
* @see JpaMetamodel
*/
@Deprecated
public interface Metamodel extends JpaMetamodel {
public interface Metamodel extends javax.persistence.metamodel.Metamodel {
/**
* Access to the SessionFactory that this Metamodel instance is bound to.
*

View File

@ -103,7 +103,7 @@ import org.hibernate.jpa.internal.PersistenceUnitUtilImpl;
import org.hibernate.mapping.RootClass;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.metamodel.internal.MetamodelImpl;
import org.hibernate.metamodel.internal.DomainMetamodelImpl;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Loadable;
@ -302,7 +302,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
LOG.debug( "Instantiated session factory" );
this.metamodel = metadata.getTypeConfiguration().scope( this );
( (MetamodelImpl) this.metamodel ).initialize(
( (DomainMetamodelImpl) this.metamodel ).initialize(
metadata,
determineJpaMetaModelPopulationSetting( properties )
);

View File

@ -65,6 +65,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -82,27 +83,43 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
* @author Emmanuel Bernard
* @author Andrea Boriero
*/
public class MetamodelImpl implements MetamodelImplementor, Serializable {
public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplementor, Serializable {
// todo : Integrate EntityManagerLogger into CoreMessageLogger
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( MetamodelImpl.class );
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( DomainMetamodelImpl.class );
private static final Object ENTITY_NAME_RESOLVER_MAP_VALUE = new Object();
private static final String INVALID_IMPORT = "";
private static final String[] EMPTY_IMPLEMENTORS = new String[0];
private final SessionFactoryImplementor sessionFactory;
private final Map<String,String> imports = new ConcurrentHashMap<>();
private final Map<String,EntityPersister> entityPersisterMap = new ConcurrentHashMap<>();
private final Map<Class,String> entityProxyInterfaceMap = new ConcurrentHashMap<>();
private final Map<String,CollectionPersister> collectionPersisterMap = new ConcurrentHashMap<>();
private final Map<String,Set<String>> collectionRolesByEntityParticipant = new ConcurrentHashMap<>();
private final ConcurrentMap<EntityNameResolver,Object> entityNameResolvers = new ConcurrentHashMap<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JpaMetamodel
private final Map<Class<?>, EntityDomainType<?>> jpaEntityTypeMap = new ConcurrentHashMap<>();
private final Map<String, EntityDomainType<?>> jpaEntityTypesByEntityName = new ConcurrentHashMap<>();
private final Map<Class<?>, MappedSuperclassType<?>> jpaMappedSuperclassTypeMap = new ConcurrentHashMap<>();
private final Set<EmbeddableDomainType<?>> jpaEmbeddableTypes = new CopyOnWriteArraySet<>();
private final Map<Class,String> entityProxyInterfaceMap = new ConcurrentHashMap<>();
private final Map<String,String> imports = new ConcurrentHashMap<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RuntimeModel
private final Map<String,EntityPersister> entityPersisterMap = new ConcurrentHashMap<>();
private final Map<String,CollectionPersister> collectionPersisterMap = new ConcurrentHashMap<>();
private final Map<String,Set<String>> collectionRolesByEntityParticipant = new ConcurrentHashMap<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DomainMetamodel
private final ConcurrentMap<EntityNameResolver,Object> entityNameResolvers = new ConcurrentHashMap<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// NOTE : Relational/mapping information is not part of the JPA metamodel
@ -124,7 +141,6 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
/**
* There can be multiple instances of an Embeddable type, each one being relative to its parent entity.
*/
private final Set<EmbeddableDomainType<?>> jpaEmbeddableTypes = new CopyOnWriteArraySet<>();
/**
* That's not strictly correct in the JPA standard since for a given Java type we could have
@ -143,7 +159,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
private final Map<String, String[]> implementorsCache = new ConcurrentHashMap<>();
public MetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
public DomainMetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
this.sessionFactory = sessionFactory;
this.typeConfiguration = typeConfiguration;
}
@ -353,7 +369,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
final RootGraphImpl entityGraph = new RootGraphImpl(
definition.getRegisteredName(),
entityType,
this
getJpaMetamodel()
);
final NamedEntityGraph namedEntityGraph = definition.getAnnotation();

View File

@ -48,7 +48,7 @@ import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
/**
* Defines a context for storing information during the building of the {@link MetamodelImpl}.
* Defines a context for storing information during the building of the {@link DomainMetamodelImpl}.
* <p/>
* This contextual information includes data needing to be processed in a second pass as well as
* cross-references into the built metamodel classes.

View File

@ -12,13 +12,14 @@ import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.spi.TypeConfiguration;
/**
* Hibernate extension to the JPA {@link javax.persistence.metamodel.Metamodel} contract
*
* @see org.hibernate.metamodel.spi.RuntimeModel
* @see DomainMetamodel
*
* @author Steve Ebersole
*/

View File

@ -9,6 +9,7 @@ package org.hibernate.metamodel.model.domain;
import javax.persistence.metamodel.PluralAttribute;
import org.hibernate.metamodel.CollectionClassification;
import org.hibernate.query.NotIndexedCollectionException;
import org.hibernate.query.sqm.SqmJoinable;
import org.hibernate.query.sqm.SqmPathSource;
@ -29,9 +30,21 @@ public interface PluralPersistentAttribute<D,C,E>
SqmPathSource getElementPathSource();
default SqmPathSource getIndexPathSource() {
throw new NotIndexedCollectionException(
"Plural attribute [" + getPathName() + "] is not indexed (list / map)"
);
}
@Override
SimpleDomainType<E> getElementType();
@Override
SimpleDomainType<E> getValueGraphType();
default SimpleDomainType<E> getKeyGraphType() {
throw new NotIndexedCollectionException(
"Plural attribute [" + getPathName() + "] is not indexed (list / map)"
);
}
}

View File

@ -11,6 +11,7 @@ import java.util.function.Consumer;
import org.hibernate.graph.RootGraph;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
@ -21,8 +22,15 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
public interface RuntimeModel {
public interface DomainMetamodel {
TypeConfiguration getTypeConfiguration();
JpaMetamodel getJpaMetamodel();
default EntityPersister resolveEntityPersister(EntityDomainType domainType) {
return findEntityDescriptor( domainType.getHibernateEntityName() );
}
EntityPersister resolveEntityPersister(Object entity);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -29,6 +29,7 @@ import org.hibernate.type.spi.TypeConfiguration;
*
* @author Steve Ebersole
*/
@Deprecated
public interface MetamodelImplementor extends Metamodel {
/**
* Access to the TypeConfiguration in effect for this SessionFactory/Metamodel

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.query;
/**
* Indicates an attempt to use a non-indexed collection as indexed.
*
* @author Steve Ebersole
*/
public class NotIndexedCollectionException extends SemanticException {
public NotIndexedCollectionException(String message) {
super( message );
}
}

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.sqm;
package org.hibernate.query;
/**
* Represents an error in the semantics (meaning) of the passed query. Generally

View File

@ -0,0 +1,22 @@
/*
* 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;
import java.util.Locale;
/**
* @author Steve Ebersole
*/
public enum TrimSpec {
LEADING,
TRAILING,
BOTH;
public String toSqlText() {
return name().toLowerCase( Locale.ROOT );
}
}

View File

@ -8,6 +8,7 @@ package org.hibernate.query.criteria;
import javax.persistence.criteria.Path;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.query.NavigablePath;
/**
@ -31,6 +32,11 @@ public interface JpaPath<T> extends JpaExpression<T>, Path<T> {
*/
<S extends T> JpaPath<S> treatAs(Class<S> treatJavaType) throws PathException;
/**
* Support for JPA's explicit (TREAT) down-casting.
*/
<S extends T> JpaPath<S> treatAs(EntityDomainType<S> treatJavaType) throws PathException;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Covariant overrides

View File

@ -25,16 +25,22 @@ import org.hibernate.internal.util.collections.Stack;
import org.hibernate.internal.util.collections.StandardStack;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.ListPersistentAttribute;
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.QueryLogger;
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.sqm.SemanticException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.StrictJpaComplianceViolation;
import org.hibernate.query.sqm.UnknownEntityException;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
@ -132,7 +138,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.sql.TrimSpec;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -1306,9 +1311,6 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmMapEntryReference visitMapEntrySelection(HqlParser.MapEntrySelectionContext ctx) {
return new SqmMapEntryReference(
consumePluralAttributeReference( ctx.path() ),
(BasicJavaDescriptor) creationContext.getDomainModel().getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Map.Entry.class ),
creationContext.getNodeBuilder()
);
}
@ -1379,7 +1381,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new ParsingException( "Expecting 2 operands to the / operator" );
}
return new SqmBinaryArithmetic<>(
//noinspection unchecked
return new SqmBinaryArithmetic(
BinaryArithmeticOperator.DIVIDE,
(SqmExpression) ctx.expression( 0 ).accept( this ),
(SqmExpression) ctx.expression( 1 ).accept( this ),
@ -1397,9 +1400,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
SqmExpression<?> dividend = (SqmExpression) ctx.expression( 0).accept( this);
SqmExpression<?> divisor = (SqmExpression) ctx.expression( 1 ).accept( this );
//noinspection unchecked
return getFunctionTemplate("mod").makeSqmFunctionExpression(
asList( dividend, divisor ),
(AllowableFunctionReturnType) dividend.getExpressableType(),
(AllowableFunctionReturnType) dividend.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1499,13 +1503,13 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public Object visitLeastFunction(HqlParser.LeastFunctionContext ctx) {
final List<SqmTypedNode<?>> arguments = new ArrayList<>();
ExpressableType<?> type = null;
SqmExpressable<?> type = null;
for ( HqlParser.ExpressionContext argument : ctx.expression() ) {
SqmTypedNode arg = (SqmTypedNode) argument.accept( this);
arguments.add(arg);
//TODO: do something better here!
type = arg.getExpressableType();
type = arg.getNodeType();
}
return getFunctionTemplate("least")
@ -1520,13 +1524,13 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public Object visitGreatestFunction(HqlParser.GreatestFunctionContext ctx) {
final List<SqmTypedNode<?>> arguments = new ArrayList<>();
ExpressableType<?> type = null;
SqmExpressable<?> type = null;
for ( HqlParser.ExpressionContext argument : ctx.expression() ) {
SqmTypedNode arg = (SqmTypedNode) argument.accept( this);
arguments.add(arg);
//TODO: do something better here!
type = arg.getExpressableType();
type = arg.getNodeType();
}
return getFunctionTemplate("greatest")
@ -1541,13 +1545,13 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitCoalesceExpression(HqlParser.CoalesceExpressionContext ctx) {
final List<SqmTypedNode<?>> arguments = new ArrayList<>();
ExpressableType<?> type = null;
SqmExpressable<?> type = null;
for ( HqlParser.ExpressionContext argument : ctx.coalesce().expression() ) {
SqmTypedNode arg = (SqmTypedNode) argument.accept( this);
arguments.add(arg);
//TODO: do something better here!
type = arg.getExpressableType();
type = arg.getNodeType();
}
return getFunctionTemplate("coalesce")
@ -1563,9 +1567,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmExpression arg1 = (SqmExpression) ctx.nullIf().expression( 0 ).accept( this );
final SqmExpression arg2 = (SqmExpression) ctx.nullIf().expression( 1 ).accept( this );
//noinspection unchecked
return getFunctionTemplate("nullif").makeSqmFunctionExpression(
asList( arg1, arg2 ),
(AllowableFunctionReturnType) arg1.getExpressableType(),
(AllowableFunctionReturnType) arg1.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1638,7 +1643,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
private SqmLiteral<Boolean> booleanLiteral(boolean value) {
final BasicValuedExpressableType expressionType = resolveExpressableTypeBasic( Boolean.class );
final SqmExpressable expressionType = resolveExpressableTypeBasic( Boolean.class );
return new SqmLiteral<>( value, expressionType, creationContext.getQueryEngine().getCriteriaBuilder() );
}
@ -1778,8 +1783,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
}
private <J> BasicValuedExpressableType<J> resolveExpressableTypeBasic(Class<J> javaType) {
return creationContext.getDomainModel().getTypeConfiguration().standardExpressableTypeForJavaType( javaType );
private <J> SqmExpressable<J> resolveExpressableTypeBasic(Class<J> javaType) {
//noinspection unchecked
return creationContext.getDomainModel().getTypeConfiguration().standardBasicTypeForJavaType( javaType );
}
@Override
@ -1889,9 +1895,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitCeilingFunction(HqlParser.CeilingFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("ceiling").makeSqmFunctionExpression(
arg,
resolveExpressableTypeBasic( Long.class ),
(AllowableFunctionReturnType) resolveExpressableTypeBasic( Long.class ),
creationContext.getQueryEngine()
);
}
@ -1900,9 +1907,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitFloorFunction(HqlParser.FloorFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("floor").makeSqmFunctionExpression(
arg,
resolveExpressableTypeBasic( Long.class ),
(AllowableFunctionReturnType) resolveExpressableTypeBasic( Long.class ),
creationContext.getQueryEngine()
);
}
@ -1915,9 +1923,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitAbsFunction(HqlParser.AbsFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("abs").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType) arg.getExpressableType(),
(AllowableFunctionReturnType) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1926,9 +1935,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitSignFunction(HqlParser.SignFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("sign").makeSqmFunctionExpression(
arg,
resolveExpressableTypeBasic( Integer.class ),
(AllowableFunctionReturnType) resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@ -1938,9 +1948,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmExpression dividend = (SqmExpression) ctx.modDividendArgument().accept( this );
final SqmExpression divisor = (SqmExpression) ctx.modDivisorArgument().accept( this );
//noinspection unchecked
return getFunctionTemplate("mod").makeSqmFunctionExpression(
asList( dividend, divisor ),
(AllowableFunctionReturnType) dividend.getExpressableType(),
(AllowableFunctionReturnType) dividend.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1950,9 +1961,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmExpression base = (SqmExpression) ctx.powerBaseArgument().accept( this );
final SqmExpression power = (SqmExpression) ctx.powerPowerArgument().accept( this );
//noinspection unchecked
return getFunctionTemplate("power").makeSqmFunctionExpression(
asList( base, power ),
(AllowableFunctionReturnType) base.getExpressableType(),
(AllowableFunctionReturnType) base.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1963,7 +1975,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate( ctx.trigFunctionName().getText() ).makeSqmFunctionExpression(
arg,
resolveExpressableTypeBasic( Double.class ),
(AllowableFunctionReturnType<Double>) resolveExpressableTypeBasic( Double.class ),
creationContext.getQueryEngine()
);
}
@ -1972,9 +1984,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitSqrtFunction(HqlParser.SqrtFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("sqrt").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType) arg.getExpressableType(),
(AllowableFunctionReturnType) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1984,9 +1997,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
final SqmExpression precision = (SqmExpression) ctx.roundFunctionPrecision().expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("round").makeSqmFunctionExpression(
asList(arg, precision),
(AllowableFunctionReturnType) arg.getExpressableType(),
(AllowableFunctionReturnType) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -1996,9 +2010,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmExpression sin = (SqmExpression) ctx.expression().get( 0).accept( this );
final SqmExpression cos = (SqmExpression) ctx.expression().get( 1).accept( this );
//noinspection unchecked
return getFunctionTemplate("atan2").makeSqmFunctionExpression(
asList(sin, cos),
(AllowableFunctionReturnType) sin.getExpressableType(),
(AllowableFunctionReturnType) sin.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -2007,9 +2022,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitLnFunction(HqlParser.LnFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("ln").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType) arg.getExpressableType(),
(AllowableFunctionReturnType) arg.getNodeType(),
creationContext.getQueryEngine()
);
@ -2019,9 +2035,10 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitExpFunction(HqlParser.ExpFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("exp").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType) arg.getExpressableType(),
(AllowableFunctionReturnType) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -2030,29 +2047,62 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public Object visitDatetimeField(HqlParser.DatetimeFieldContext ctx) {
NodeBuilder nodeBuilder = creationContext.getNodeBuilder();
if (ctx.DAY()!=null) {
return new SqmExtractUnit<>( "day", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"day",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.MONTH()!=null) {
return new SqmExtractUnit<>( "month", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"month",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.YEAR()!=null) {
return new SqmExtractUnit<>( "year", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"year",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.HOUR()!=null) {
return new SqmExtractUnit<>( "hour", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"hour",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.MINUTE()!=null) {
return new SqmExtractUnit<>( "minute", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"minute",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.SECOND()!=null) {
return new SqmExtractUnit<>( "second", resolveExpressableTypeBasic( Float.class ), nodeBuilder);
return new SqmExtractUnit<>(
"second",
(AllowableFunctionReturnType<Float>) resolveExpressableTypeBasic( Float.class ),
nodeBuilder
);
}
if (ctx.WEEK()!=null) {
return new SqmExtractUnit<>( "week", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"week",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.QUARTER()!=null) {
return new SqmExtractUnit<>( "quarter", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"quarter",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
return super.visitDatetimeField(ctx);
}
@ -2061,11 +2111,19 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
NodeBuilder nodeBuilder = creationContext.getNodeBuilder();
if (ctx.MICROSECOND()!=null) {
//TODO: need to go back to the dialect, it's called "microseconds" on some
return new SqmExtractUnit<>( "microsecond", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"microsecond",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.MILLISECOND()!=null) {
//TODO: need to go back to the dialect, it's called "milliseconds" on some
return new SqmExtractUnit<>( "millisecond", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"millisecond",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
return super.visitSecondsField(ctx);
}
@ -2074,10 +2132,18 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public Object visitTimeZoneField(HqlParser.TimeZoneFieldContext ctx) {
NodeBuilder nodeBuilder = creationContext.getNodeBuilder();
if (ctx.TIMEZONE_HOUR()!=null) {
return new SqmExtractUnit<>( "timezone_hour", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"timezone_hour",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
if (ctx.TIMEZONE_MINUTE()!=null) {
return new SqmExtractUnit<>( "timezone_minute", resolveExpressableTypeBasic( Integer.class ), nodeBuilder);
return new SqmExtractUnit<>(
"timezone_minute",
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
return super.visitTimeZoneField(ctx);
}
@ -2097,6 +2163,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return expressionToExtract;
}
//noinspection unchecked
return getFunctionTemplate("extract").makeSqmFunctionExpression(
asList( extractFieldExpression, expressionToExtract ),
extractFieldExpression.getType(),
@ -2136,24 +2203,66 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
String text = castTargetContext.identifier().getText();
NodeBuilder nodeBuilder = creationContext.getNodeBuilder();
switch (text.toLowerCase()) {
case "string": return new SqmCastTarget<>( resolveExpressableTypeBasic( String.class ), nodeBuilder );
case "integer": return new SqmCastTarget<>( resolveExpressableTypeBasic( Integer.class ), nodeBuilder );
case "long": return new SqmCastTarget<>( resolveExpressableTypeBasic( Long.class ), nodeBuilder );
case "float": return new SqmCastTarget<>( resolveExpressableTypeBasic( Float.class ), nodeBuilder );
case "double": return new SqmCastTarget<>( resolveExpressableTypeBasic( Double.class ), nodeBuilder );
case "time": return new SqmCastTarget<>( resolveExpressableTypeBasic( Time.class ), nodeBuilder );
case "date": return new SqmCastTarget<>( resolveExpressableTypeBasic( Date.class ), nodeBuilder );
case "timestamp": return new SqmCastTarget<>( resolveExpressableTypeBasic( Timestamp.class ), nodeBuilder );
default: throw new SqmProductionException( "unrecognized cast target type: " + text);
case "string": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
nodeBuilder
);
}
case "integer": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
nodeBuilder
);
}
case "long": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Long>) resolveExpressableTypeBasic( Long.class ), nodeBuilder
);
}
case "float": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Float>) resolveExpressableTypeBasic( Float.class ),
nodeBuilder
);
}
case "double": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Double>) resolveExpressableTypeBasic( Double.class ),
nodeBuilder
);
}
case "time": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Time>) resolveExpressableTypeBasic( Time.class ),
nodeBuilder
);
}
case "date": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Date>) resolveExpressableTypeBasic( Date.class ),
nodeBuilder
);
}
case "timestamp": {
return new SqmCastTarget<>(
(AllowableFunctionReturnType<Timestamp>) resolveExpressableTypeBasic( Timestamp.class ),
nodeBuilder
);
}
default: {
throw new SqmProductionException( "unrecognized cast target type: " + text);
}
}
}
@Override
public SqmExpression visitUpperFunction(HqlParser.UpperFunctionContext ctx) {
final SqmExpression expression = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("upper").makeSqmFunctionExpression(
expression,
(BasicValuedExpressableType) expression.getExpressableType(),
(AllowableFunctionReturnType) expression.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -2165,14 +2274,13 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final SqmExpression expression = (SqmExpression) ctx.expression().accept( this );
return getFunctionTemplate("lower").makeSqmFunctionExpression(
expression,
(BasicValuedExpressableType) expression.getExpressableType(),
(AllowableFunctionReturnType) expression.getNodeType(),
creationContext.getQueryEngine()
);
}
@Override
public SqmExpression visitConcatFunction(HqlParser.ConcatFunctionContext ctx) {
final List<SqmTypedNode<?>> arguments = new ArrayList<>();
for ( HqlParser.ExpressionContext argument : ctx.expression() ) {
arguments.add( (SqmTypedNode<?>) argument.accept( this ) );
@ -2180,39 +2288,36 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("concat").makeSqmFunctionExpression(
arguments,
resolveExpressableTypeBasic( String.class ),
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
}
@Override
public Object visitLengthFunction(HqlParser.LengthFunctionContext ctx) {
final SqmExpression arg = (SqmExpression) ctx.expression().accept( this );
return getFunctionTemplate("character_length").makeSqmFunctionExpression(
arg,
resolveExpressableTypeBasic( Integer.class ),
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@Override
public Object visitPositionFunction(HqlParser.PositionFunctionContext ctx) {
final SqmExpression<?> string = (SqmExpression) ctx.positionFunctionStringArgument().accept( this );
final SqmExpression<?> pattern = (SqmExpression) ctx.positionFunctionPatternArgument().accept( this );
return getFunctionTemplate("locate").makeSqmFunctionExpression(
asList( pattern, string ),
resolveExpressableTypeBasic( Integer.class ),
(AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@Override
public Object visitLocateFunction(HqlParser.LocateFunctionContext ctx) {
final SqmExpression<?> string = (SqmExpression) ctx.locateFunctionStringArgument().accept( this );
final SqmExpression<?> pattern = (SqmExpression) ctx.locateFunctionPatternArgument().accept( this );
final SqmExpression<?> start = ctx.locateFunctionStartArgument() == null
@ -2223,7 +2328,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
start == null
? asList( pattern, string )
: asList( pattern, string, start ),
resolveExpressableTypeBasic( Integer.class ),
( AllowableFunctionReturnType<Integer>) resolveExpressableTypeBasic( Integer.class ),
creationContext.getQueryEngine()
);
}
@ -2237,7 +2342,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("replace").makeSqmFunctionExpression(
asList( string, pattern, replacement ),
resolveExpressableTypeBasic( String.class ),
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
}
@ -2245,7 +2350,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
@Override
public Object visitStrFunction(HqlParser.StrFunctionContext ctx) {
final SqmExpression<?> arg = (SqmExpression) ctx.expression().accept( this );
BasicValuedExpressableType<String> type = resolveExpressableTypeBasic( String.class );
AllowableFunctionReturnType<String> type = (AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class );
return getFunctionTemplate("cast").makeSqmFunctionExpression(
asList( arg, new SqmCastTarget<>( type, creationContext.getNodeBuilder() ) ),
type,
@ -2259,7 +2364,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
//ignore DISTINCT
return getFunctionTemplate("max").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType<?>) arg.getExpressableType(),
(AllowableFunctionReturnType<?>) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -2270,7 +2375,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
//ignore DISTINCT
return getFunctionTemplate("min").makeSqmFunctionExpression(
arg,
(AllowableFunctionReturnType<?>) arg.getExpressableType(),
(AllowableFunctionReturnType<?>) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -2283,7 +2388,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("sum").makeSqmFunctionExpression(
argument,
(AllowableFunctionReturnType<?>) arg.getExpressableType(),
(AllowableFunctionReturnType<?>) arg.getNodeType(),
creationContext.getQueryEngine()
);
}
@ -2296,7 +2401,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("avg").makeSqmFunctionExpression(
argument,
resolveExpressableTypeBasic( Double.class ),
(AllowableFunctionReturnType<Double>) resolveExpressableTypeBasic( Double.class ),
creationContext.getQueryEngine()
);
}
@ -2311,7 +2416,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("count").makeSqmFunctionExpression(
argument,
resolveExpressableTypeBasic( Long.class ),
(AllowableFunctionReturnType<Long>) resolveExpressableTypeBasic( Long.class ),
creationContext.getQueryEngine()
);
}
@ -2326,7 +2431,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return getFunctionTemplate("substring").makeSqmFunctionExpression(
length==null ? asList( source, start ) : asList( source, start, length ),
resolveExpressableTypeBasic( String.class ),
(AllowableFunctionReturnType<String>) resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
@ -2336,13 +2441,14 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmExpression visitTrimFunction(HqlParser.TrimFunctionContext ctx) {
final SqmExpression source = (SqmExpression) ctx.expression().accept( this );
//noinspection unchecked
return getFunctionTemplate("trim").makeSqmFunctionExpression(
asList(
interpretTrimSpecification( ctx.trimSpecification() ),
visitTrimCharacter( ctx.trimCharacter() ),
source
),
resolveExpressableTypeBasic( String.class ),
(AllowableFunctionReturnType) resolveExpressableTypeBasic( String.class ),
creationContext.getQueryEngine()
);
}
@ -2415,27 +2521,22 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new ParsingException( "Could not resolve identification variable [" + alias + "] to SqmFrom" );
}
final PluralValuedNavigable pluralValuedNavigable = sqmFrom.sqmAs(
PluralValuedNavigable.class,
() -> new ParsingException( "Could not resolve identification variable [" + alias + "] as plural-attribute" )
);
final SqmPathSource<?> pluralAttribute = sqmFrom.getReferencedPathSource();
if ( pluralValuedNavigable.getCollectionDescriptor().getIndexDescriptor() == null ) {
throw new SemanticException(
"index() function can only be applied to identification variables which resolve to an " +
"indexed collection (map,list); specified identification variable [" + alias +
"] resolved to " + sqmFrom
);
if ( !( pluralAttribute instanceof PluralPersistentAttribute ) ) {
throw new ParsingException( "Could not resolve identification variable [" + alias + "] as plural-attribute" )
}
return pluralValuedNavigable.getCollectionDescriptor()
.getIndexDescriptor()
.createSqmExpression( sqmFrom, this );
//noinspection unchecked
return ( (PluralPersistentAttribute) pluralAttribute ).getIndexPathSource().createSqmPath(
sqmFrom,
this
);
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isIndexedPluralAttribute(SqmPath path) {
return path.getReferencedPathSource() instanceof PluralValuedNavigable;
return path.getReferencedPathSource() instanceof PluralPersistentAttribute;
}
@Override
@ -2444,6 +2545,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION );
}
//noinspection unchecked
return new SqmMaxElementPath( consumePluralAttributeReference( ctx.path() ) );
}
@ -2453,6 +2555,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
throw new StrictJpaComplianceViolation( StrictJpaComplianceViolation.Type.HQL_COLLECTION_FUNCTION );
}
//noinspection unchecked
return new SqmMinElementPath( consumePluralAttributeReference( ctx.path() ) );
}
@ -2471,6 +2574,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
);
}
//noinspection unchecked
return new SqmMaxIndexPath( pluralPath );
}
@ -2489,6 +2593,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
);
}
//noinspection unchecked
return new SqmMinIndexPath( pluralPath );
}
@ -2576,6 +2681,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
else if ( ctx.dotIdentifierSequence() != null && ctx.indexedPathAccessFragment() != null ) {
final SqmAttributeJoin indexedJoinPath = (SqmAttributeJoin) ctx.dotIdentifierSequence().accept( this );
//noinspection unchecked
return new SqmIndexedCollectionAccessPath(
indexedJoinPath,
(SqmExpression) ctx.indexedPathAccessFragment().accept( this )
@ -2623,7 +2729,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmPath<?> visitTreatedNavigablePath(HqlParser.TreatedNavigablePathContext ctx) {
final SqmPath<?> sqmPath = consumeNavigableContainerReference( ctx.path() );
final String treatTargetName = ctx.dotIdentifierSequence().getText();
final EntityTypeDescriptor<Object> treatTarget = getCreationContext().getDomainModel().getEntityDescriptor( treatTargetName );
final EntityDomainType<?> treatTarget = getCreationContext().getDomainModel().entity( treatTargetName );
SqmPath<?> result = resolveTreatedPath( sqmPath, treatTarget );
@ -2644,32 +2750,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
@SuppressWarnings("unchecked")
private SqmTreatedPath resolveTreatedPath(SqmPath<?> sqmPath, EntityTypeDescriptor<Object> treatTarget) {
if ( sqmPath instanceof SqmRoot ) {
return new SqmTreatedRoot( (SqmRoot) sqmPath, treatTarget, null );
}
assert sqmPath instanceof SqmJoin;
final Navigable<?> navigable = sqmPath.getReferencedPathSource();
if ( navigable instanceof SingularPersistentAttribute ) {
return new SqmTreatedSingularJoin( (SqmSingularJoin) sqmPath, treatTarget, null );
}
else if ( navigable instanceof BagPersistentAttribute ) {
return new SqmTreatedBagJoin( (SqmBagJoin) sqmPath, treatTarget, null );
}
else if ( navigable instanceof ListPersistentAttribute ) {
return new SqmTreatedListJoin( (SqmListJoin) sqmPath, treatTarget, null );
}
else if ( navigable instanceof SqmSetJoin ) {
return new SqmTreatedSetJoin( (SqmSetJoin) sqmPath, treatTarget, null );
}
else if ( navigable instanceof MapPersistentAttribute ) {
return new SqmTreatedMapJoin( (SqmMapJoin) sqmPath, treatTarget, null );
}
throw new UnsupportedOperationException( "Path [" + sqmPath + "] cannot be treated (downcast)" );
private SqmTreatedPath resolveTreatedPath(SqmPath<?> sqmPath, EntityDomainType<?> treatTarget) {
return sqmPath.treatAs( (EntityDomainType) treatTarget );
}
@Override

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.query.sqm;
import org.hibernate.query.SemanticException;
/**
* @author Andrea Boriero
*/

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.query.sqm;
import org.hibernate.query.SemanticException;
/**
* @author Steve Ebersole
*/

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.query.sqm;
import org.hibernate.query.SemanticException;
/**
* The root exception for errors (potential bugs) in the sqm parser code itself, as opposed
* to {@link SemanticException} which indicates problems with the sqm.

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.query.sqm;
import org.hibernate.query.SemanticException;
/**
* Indicates violations of strict JPQL syntax while strict JPQL syntax checking was enabled.
*

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.query.sqm;
import org.hibernate.query.SemanticException;
/**
* Indicates we were not able to resolve a given "path structure" as an entity name.
* <p/>

View File

@ -8,6 +8,7 @@ package org.hibernate.query.sqm;
import java.util.Locale;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.tree.domain.SqmPath;
/**

View File

@ -49,7 +49,7 @@ import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.spi.ComparisonOperator;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.produce.function.SqmFunctionTemplate;
import org.hibernate.query.sqm.tree.expression.function.SqmCastTarget;
import org.hibernate.query.sqm.tree.expression.function.SqmDistinct;

View File

@ -41,7 +41,7 @@
*
* Generally, the interpretation will throw exceptions as one of 3 types:
*
* * {@link org.hibernate.query.sqm.SemanticException} and derivatives represent problems with the
* * {@link org.hibernate.query.SemanticException} and derivatives represent problems with the
* query itself.
* * {@link org.hibernate.query.sqm.ParsingException} and derivatives represent errors (potential
* bugs) during parsing.

View File

@ -36,7 +36,7 @@ import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.JpaPath;
import org.hibernate.query.criteria.JpaSubQuery;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.UnknownPathException;
import org.hibernate.query.sqm.produce.path.spi.SemanticPathPart;

View File

@ -20,6 +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.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -123,9 +124,13 @@ public class SqmBagJoin<O, E> extends AbstractSqmPluralJoin<O,Collection<E>, E>
@Override
public <S extends E> SqmTreatedBagJoin<O, E, S> treatAs(Class<S> treatAsType) {
final EntityDomainType<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
return (SqmTreatedBagJoin<O, E, S>) treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedBagJoin( this, entityTypeDescriptor, null );
return new SqmTreatedBagJoin( this, treatTarget, null );
}
@Override

View File

@ -9,7 +9,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.query.NavigablePath;
import org.hibernate.query.criteria.PathException;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
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,6 +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.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -99,12 +100,15 @@ public class SqmListJoin<O,E> extends AbstractSqmPluralJoin<O,List<E>, E> implem
}
@Override
@SuppressWarnings("unchecked")
public <S extends E> SqmTreatedListJoin<O,E,S> treatAs(Class<S> treatAsType) {
final EntityDomainType<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
return new SqmTreatedListJoin( this, entityTypeDescriptor, null );
return (SqmTreatedListJoin<O,E,S>) treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedListJoin( this, treatTarget, null );
}
@Override
public <A> SqmSingularJoin<E, A> fetch(SingularAttribute<? super E, A> attribute) {

View File

@ -168,10 +168,14 @@ public class SqmMapJoin<O,K,V> extends AbstractSqmPluralJoin<O,Map<K,V>,V> imple
}
@Override
@SuppressWarnings("unchecked")
public <S extends V> SqmTreatedMapJoin<O,K,V,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> targetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedMapJoin( this, targetDescriptor, null );
return (SqmTreatedMapJoin<O,K,V,S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends V> SqmTreatedPath<V, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedMapJoin( this, treatTarget, null );
}
@Override

View File

@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
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

@ -8,7 +8,7 @@ package org.hibernate.query.sqm.tree.domain;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
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

@ -6,11 +6,12 @@
*/
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.sqm.ParsingException;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.SqmPathSource;
import org.hibernate.query.sqm.produce.SqmCreationHelper;
@ -72,6 +73,9 @@ public interface SqmPath<T> extends SqmExpression<T>, SemanticPathPart, JpaPath<
@Override
<S extends T> SqmTreatedPath<T,S> treatAs(Class<S> treatJavaType) throws PathException;
@Override
<S extends T> SqmTreatedPath<T,S> treatAs(EntityDomainType<S> treatTarget) throws PathException;
default SqmRoot findRoot() {
final SqmPath lhs = getLhs();
if ( lhs != null ) {

View File

@ -20,6 +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.sqm.NodeBuilder;
import org.hibernate.query.sqm.produce.SqmCreationProcessingState;
import org.hibernate.query.sqm.tree.SqmJoinType;
@ -92,8 +93,12 @@ public class SqmSetJoin<O, E>
@Override
public <S extends E> SqmTreatedSetJoin<O,E,S> treatAs(Class<S> treatAsType) {
final EntityDomainType<S> entityTypeDescriptor = nodeBuilder().getDomainModel().entity( treatAsType );
return new SqmTreatedSetJoin<>( this, entityTypeDescriptor, null );
return (SqmTreatedSetJoin<O,E,S>) treatAs( nodeBuilder().getDomainModel().entity( treatAsType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
return new SqmTreatedSetJoin<>( this, treatTarget, null );
}
// todo (6.0) : need to resolve these fetches against the element/index descriptors

View File

@ -44,9 +44,13 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
@Override
public <S extends T> SqmTreatedSingularJoin<O,T,S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> targetDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return (SqmTreatedSingularJoin<O,T,S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends T> SqmTreatedPath<T, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
//noinspection unchecked
return new SqmTreatedSingularJoin( this, targetDescriptor, null );
return new SqmTreatedSingularJoin( this, treatTarget, null );
}
@Override

View File

@ -6,12 +6,11 @@
*/
package org.hibernate.query.sqm.tree.expression;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.query.BinaryArithmeticOperator;
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.BasicValuedExpressableType;
/**
* @author Steve Ebersole
@ -25,13 +24,13 @@ public class SqmBinaryArithmetic<T> extends AbstractSqmExpression<T> {
BinaryArithmeticOperator operator,
SqmExpression<?> lhsOperand,
SqmExpression<?> rhsOperand,
MetamodelImplementor domainModel,
JpaMetamodel domainModel,
NodeBuilder nodeBuilder) {
//noinspection unchecked
super(
(SqmExpressable<T>) domainModel.getTypeConfiguration().resolveArithmeticType(
(BasicValuedExpressableType) lhsOperand.getNodeType(),
(BasicValuedExpressableType) rhsOperand.getNodeType(),
lhsOperand.getNodeType(),
rhsOperand.getNodeType(),
operator
),
nodeBuilder
@ -49,7 +48,7 @@ public class SqmBinaryArithmetic<T> extends AbstractSqmExpression<T> {
BinaryArithmeticOperator operator,
SqmExpression<?> lhsOperand,
SqmExpression<?> rhsOperand,
BasicValuedExpressableType<T> expressableType,
SqmExpressable<T> expressableType,
NodeBuilder nodeBuilder) {
super( expressableType, nodeBuilder );
@ -62,12 +61,7 @@ public class SqmBinaryArithmetic<T> extends AbstractSqmExpression<T> {
}
@Override
public BasicValuedExpressableType<T> getNodeType() {
return (BasicValuedExpressableType<T>) super.getNodeType();
}
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitBinaryArithmeticExpression( this );
}

View File

@ -8,14 +8,13 @@ package org.hibernate.query.sqm.tree.expression;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.sql.ast.produce.metamodel.spi.BasicValuedExpressableType;
import org.hibernate.sql.results.spi.DomainResult;
import org.hibernate.sql.results.spi.DomainResultCreationState;
import org.hibernate.sql.results.spi.DomainResultProducer;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
import org.hibernate.type.spi.StandardSpiBasicTypes;
import org.hibernate.type.StandardBasicTypes;
/**
* Represents the {@code SIZE()} function.
@ -27,10 +26,11 @@ public class SqmCollectionSize extends AbstractSqmExpression<Integer> implements
private final SqmPath pluralPath;
public SqmCollectionSize(SqmPath<?> pluralPath, NodeBuilder nodeBuilder) {
this( pluralPath, StandardSpiBasicTypes.INTEGER, nodeBuilder );
//noinspection unchecked
this( pluralPath, StandardBasicTypes.INTEGER, nodeBuilder );
}
public SqmCollectionSize(SqmPath<?> pluralPath, BasicValuedExpressableType<Integer> sizeType, NodeBuilder nodeBuilder) {
public SqmCollectionSize(SqmPath<?> pluralPath, SqmExpressable<Integer> sizeType, NodeBuilder nodeBuilder) {
super( sizeType, nodeBuilder );
this.pluralPath = pluralPath;
}
@ -39,11 +39,6 @@ public class SqmCollectionSize extends AbstractSqmExpression<Integer> implements
return pluralPath;
}
@Override
public BasicValuedExpressableType<Integer> getNodeType() {
return (BasicValuedExpressableType<Integer>) super.getNodeType();
}
@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
return walker.visitPluralAttributeSizeFunction( this );
@ -65,9 +60,4 @@ public class SqmCollectionSize extends AbstractSqmExpression<Integer> implements
// getNodeType()
// );
}
@Override
public JavaTypeDescriptor getJavaTypeDescriptor() {
return getNodeType().getJavaTypeDescriptor();
}
}

View File

@ -7,8 +7,8 @@
package org.hibernate.query.sqm.tree.expression;
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.BasicValuedExpressableType;
/**
* Represents a literal value in the sqm, e.g.<ul>
@ -23,7 +23,7 @@ import org.hibernate.sql.ast.produce.metamodel.spi.BasicValuedExpressableType;
public class SqmLiteral<T> extends AbstractSqmExpression<T> implements SqmExpression<T> {
private T value;
public SqmLiteral(T value, BasicValuedExpressableType<T> inherentType, NodeBuilder nodeBuilder) {
public SqmLiteral(T value, SqmExpressable<T> inherentType, NodeBuilder nodeBuilder) {
super( inherentType, nodeBuilder );
this.value = value;
}
@ -32,11 +32,6 @@ public class SqmLiteral<T> extends AbstractSqmExpression<T> implements SqmExpres
return value;
}
@Override
public BasicValuedExpressableType<T> getNodeType() {
return (BasicValuedExpressableType<T>) super.getNodeType();
}
@Override
public <R> R accept(SemanticQueryWalker<R> walker) {
return walker.visitLiteral( this );

View File

@ -7,7 +7,7 @@
package org.hibernate.query.sqm.tree.expression;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SemanticException;
import org.hibernate.query.SemanticException;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.sql.ast.produce.metamodel.spi.EntityValuedExpressableType;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;

View File

@ -6,14 +6,13 @@
*/
package org.hibernate.query.sqm.tree.expression.function;
import org.hibernate.query.TrimSpec;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.AbstractSqmNode;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.SqmVisitableNode;
import org.hibernate.sql.TrimSpec;
import org.hibernate.sql.ast.produce.metamodel.spi.ExpressableType;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
/**
* Needed to pass TrimSpecification as an SqmExpression when we call out to
@ -22,7 +21,6 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptor;
* @author Steve Ebersole
*/
public class SqmTrimSpecification extends AbstractSqmNode implements SqmTypedNode, SqmVisitableNode {
private final TrimSpec specification;
public SqmTrimSpecification(TrimSpec specification, NodeBuilder nodeBuilder) {
@ -45,7 +43,7 @@ public class SqmTrimSpecification extends AbstractSqmNode implements SqmTypedNod
}
@Override
public ExpressableType getNodeType() {
public SqmExpressable getNodeType() {
return null;
}
}

View File

@ -13,6 +13,7 @@ import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.domain.AbstractSqmFrom;
import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedPath;
import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -80,7 +81,11 @@ public class SqmRoot<E> extends AbstractSqmFrom<E,E> implements JpaRoot<E> {
@Override
public <S extends E> SqmTreatedRoot<E, S> treatAs(Class<S> treatJavaType) throws PathException {
final EntityDomainType<S> typeDescriptor = nodeBuilder().getDomainModel().entity( treatJavaType );
return new SqmTreatedRoot<>( this, typeDescriptor, nodeBuilder() );
return (SqmTreatedRoot<E, S>) treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ) );
}
@Override
public <S extends E> SqmTreatedPath<E, S> treatAs(EntityDomainType<S> treatTarget) throws PathException {
return new SqmTreatedRoot<>( this, treatTarget, nodeBuilder() );
}
}

View File

@ -6,8 +6,6 @@
*/
package org.hibernate.type;
import org.hibernate.type.descriptor.sql.ObjectSqlTypeDescriptor;
/**
* Centralizes access to the standard set of basic {@link Type types}.
* <p/>

View File

@ -0,0 +1,34 @@
/*
* 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.type.internal;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* @author Steve Ebersole
*/
public class StandardBasicTypeImpl<J> extends AbstractSingleColumnStandardBasicType {
public static final String[] NO_REG_KEYS = new String[0];
public StandardBasicTypeImpl(JavaTypeDescriptor<J> jtd, SqlTypeDescriptor std) {
super( std, jtd );
}
@Override
public String[] getRegistrationKeys() {
// irrelevant - these are created on-the-fly
return NO_REG_KEYS;
}
@Override
public String getName() {
// again, irrelevant
return null;
}
}

View File

@ -8,6 +8,8 @@ package org.hibernate.type.spi;
import java.io.InvalidObjectException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
@ -16,6 +18,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import org.hibernate.HibernateException;
import org.hibernate.Incubating;
@ -28,20 +31,26 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.id.uuid.LocalObjectUuidHelper;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.SessionFactoryRegistry;
import org.hibernate.metamodel.internal.MetamodelImpl;
import org.hibernate.metamodel.internal.DomainMetamodelImpl;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.internal.QueryHelper;
import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.type.TypeResolver;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptorIndicators;
import org.hibernate.type.descriptor.sql.spi.SqlTypeDescriptorRegistry;
import org.hibernate.type.internal.StandardBasicTypeImpl;
import org.hibernate.type.internal.TypeConfigurationRegistry;
import static org.hibernate.internal.CoreLogging.messageLogger;
import static org.hibernate.query.BinaryArithmeticOperator.DIVIDE;
/**
* Defines a set of available Type instances as isolated from other configurations. The
@ -175,7 +184,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
scope.setSessionFactory( sessionFactory );
sessionFactory.addObserver( this );
return new MetamodelImpl( sessionFactory, this );
return new DomainMetamodelImpl( sessionFactory, this );
}
/**
@ -409,4 +418,127 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
log.trace( "Resolving serialized TypeConfiguration - readResolve" );
return TypeConfigurationRegistry.INSTANCE.findTypeConfiguration( getUuid() );
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @see QueryHelper#highestPrecedenceType2
*/
public SqmExpressable<?> resolveArithmeticType(
SqmExpressable<?> firstType,
SqmExpressable<?> secondType,
BinaryArithmeticOperator operator) {
return resolveArithmeticType( firstType, secondType, operator == DIVIDE );
}
/**
* Determine the result type of an arithmetic operation as defined by the
* rules in section 6.5.7.1.
*
* @see QueryHelper#highestPrecedenceType2
*/
public SqmExpressable<?> resolveArithmeticType(
SqmExpressable<?> firstType,
SqmExpressable<?> secondType,
boolean isDivision) {
if ( isDivision ) {
// covered under the note in 6.5.7.1 discussing the unportable
// "semantics of the SQL division operation"..
return getBasicTypeRegistry().getRegisteredType( Number.class.getName() );
}
// non-division
if ( matchesJavaType( firstType, Double.class ) ) {
return firstType;
}
else if ( matchesJavaType( secondType, Double.class ) ) {
return secondType;
}
else if ( matchesJavaType( firstType, Float.class ) ) {
return firstType;
}
else if ( matchesJavaType( secondType, Float.class ) ) {
return secondType;
}
else if ( matchesJavaType( firstType, BigDecimal.class ) ) {
return firstType;
}
else if ( matchesJavaType( secondType, BigDecimal.class ) ) {
return secondType;
}
else if ( matchesJavaType( firstType, BigInteger.class ) ) {
return firstType;
}
else if ( matchesJavaType( secondType, BigInteger.class ) ) {
return secondType;
}
else if ( matchesJavaType( firstType, Long.class ) ) {
return firstType;
}
else if ( matchesJavaType( secondType, Long.class ) ) {
return secondType;
}
else if ( matchesJavaType( firstType, Integer.class ) ) {
return firstType;
}
else if ( matchesJavaType( secondType, Integer.class ) ) {
return secondType;
}
else if ( matchesJavaType( firstType, Short.class ) ) {
return getBasicTypeRegistry().getRegisteredType( Integer.class.getName() );
}
else if ( matchesJavaType( secondType, Short.class ) ) {
return getBasicTypeRegistry().getRegisteredType( Integer.class.getName() );
}
else {
return getBasicTypeRegistry().getRegisteredType( Number.class.getName() );
}
}
@SuppressWarnings("unchecked")
private static boolean matchesJavaType(SqmExpressable type, Class javaType) {
assert javaType != null;
return type != null && javaType.isAssignableFrom( type.getExpressableJavaTypeDescriptor().getJavaType() );
}
private final ConcurrentHashMap<Class,BasicType> basicTypeByJavaType = new ConcurrentHashMap<>();
public BasicType standardBasicTypeForJavaType(Class<?> javaType) {
if ( javaType == null ) {
return null;
}
//noinspection unchecked
return standardBasicTypeForJavaType(
javaType,
javaTypeDescriptor -> new StandardBasicTypeImpl(
javaTypeDescriptor,
javaTypeDescriptor.getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() )
)
);
}
public BasicType standardBasicTypeForJavaType(
Class<?> javaType,
Function<JavaTypeDescriptor<?>,BasicType> creator) {
if ( javaType == null ) {
return null;
}
return basicTypeByJavaType.computeIfAbsent(
javaType,
jt -> {
final JavaTypeDescriptor javaTypeDescriptor = javaTypeDescriptorRegistry.resolveDescriptor( javaType );
return creator.apply( javaTypeDescriptor );
}
);
}
}

View File

@ -34,7 +34,7 @@ import org.hibernate.jpa.test.metamodel.Phone;
import org.hibernate.jpa.test.metamodel.Product;
import org.hibernate.jpa.test.metamodel.ShelfLife;
import org.hibernate.jpa.test.metamodel.Spouse;
import org.hibernate.metamodel.internal.MetamodelImpl;
import org.hibernate.metamodel.internal.DomainMetamodelImpl;
import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.predicate.ComparisonPredicate;
@ -77,7 +77,7 @@ public class QueryBuilderTest extends BaseEntityManagerFunctionalTestCase {
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
DomainMetamodelImpl mm = (DomainMetamodelImpl) em.getMetamodel();
CriteriaQuery<Integer> cquery = cb.createQuery( Integer.class );
Root<Product> product = cquery.from( Product.class );
@ -135,7 +135,7 @@ public class QueryBuilderTest extends BaseEntityManagerFunctionalTestCase {
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
DomainMetamodelImpl mm = (DomainMetamodelImpl) em.getMetamodel();
EntityType<Phone> Phone_ = mm.entity( Phone.class );
CriteriaQuery<Phone> cquery = cb.createQuery( Phone.class );
@ -157,7 +157,7 @@ public class QueryBuilderTest extends BaseEntityManagerFunctionalTestCase {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
DomainMetamodelImpl mm = (DomainMetamodelImpl) em.getMetamodel();
EntityType<Product> Product_ = mm.entity( Product.class );
// toFloat
@ -189,7 +189,7 @@ public class QueryBuilderTest extends BaseEntityManagerFunctionalTestCase {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
DomainMetamodelImpl mm = (DomainMetamodelImpl) em.getMetamodel();
CriteriaQuery<Customer> cquery = cb.createQuery(Customer.class);
Root<Customer> customer = cquery.from(Customer.class);
@ -236,7 +236,7 @@ public class QueryBuilderTest extends BaseEntityManagerFunctionalTestCase {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
CriteriaBuilderImpl cb = (CriteriaBuilderImpl) em.getCriteriaBuilder();
MetamodelImpl mm = (MetamodelImpl) em.getMetamodel();
DomainMetamodelImpl mm = (DomainMetamodelImpl) em.getMetamodel();
CriteriaQuery<java.sql.Date> dateQuery = cb.createQuery(java.sql.Date.class);
dateQuery.from( Customer.class );

View File

@ -29,7 +29,7 @@ import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.MetamodelImpl;
import org.hibernate.metamodel.internal.DomainMetamodelImpl;
import org.junit.Test;
@ -94,7 +94,7 @@ public class MetadataTest extends BaseEntityManagerFunctionalTestCase {
.addAnnotatedClass( WithGenericCollection.class )
.buildMetadata();
SessionFactoryImplementor sfi = (SessionFactoryImplementor) metadata.buildSessionFactory();
MetamodelImpl metamodel = new MetamodelImpl( sfi, ( (MetadataImplementor) metadata ).getTypeConfiguration() );
DomainMetamodelImpl metamodel = new DomainMetamodelImpl( sfi, ( (MetadataImplementor) metadata ).getTypeConfiguration() );
metamodel.initialize( (MetadataImplementor) metadata, JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED );
sfi.close();
}