6 - SQM based on JPA type system

This commit is contained in:
Steve Ebersole 2019-05-24 16:49:08 -05:00 committed by Andrea Boriero
parent 0ce1c35d95
commit f25ed96df6
11 changed files with 244 additions and 85 deletions

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 defining Hibernate's boot-time metamodel, which is an
* incrementally built understanding of the application's domain
* model (its entities, attributes, etc).
*
* Ultimately, as part of the process of creating the
* {@link org.hibernate.SessionFactory}, Hibernate will interpret
* this boot metamodel to its runtime metamodel.
*/
package org.hibernate.boot.model;

View File

@ -0,0 +1,56 @@
/*
* 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.metamodel.internal;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.hibernate.EntityNameResolver;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class InflightRuntimeMetamodel {
private final TypeConfiguration typeConfiguration;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hibernate metamodel
private final Map<String, EntityPersister> entityPersisterMap = new HashMap<>();
private Map<Class, String> entityProxyInterfaceMap;
private Map<String, CollectionPersister> collectionPersisterMap;
private Map<String, Set<String>> collectionRolesByEntityParticipant;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA metamodel
private final Map<String, EntityDomainType<?>> jpaEntityTypeMap = new HashMap<>();
private Map<Class, MappedSuperclassDomainType<?>> jpaMappedSuperclassTypeMap;
private Map<Class, EmbeddableDomainType<?>> embeddableDescriptorMap;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Misc
private final Map<String, String> nameToImportNameMap = new HashMap<>();
private Set<EntityNameResolver> entityNameResolvers;
public InflightRuntimeMetamodel(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
}

View File

@ -0,0 +1,99 @@
/*
* 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.metamodel.internal;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.metamodel.spi.MetamodelImplementor;
/**
* Responsible for interpreting the Hibernate boot metamodel into
* its runtime metamodel
*
* @see org.hibernate.boot.model
* @see org.hibernate.metamodel
*
* @author Steve Ebersole
*/
public class RuntimeModelCreationProcess {
// todo (6.0) : look at removing reliance on SessionFactory here as well. Just pass in what we need.
// See RuntimeModelCreationContext. Ultimately we will need SessionFactory to create the persisters
//
// todo (6.0) : ^^ A running list of what we use from SessionFactory:
// - ServiceRegistry
// - Properties
// - Cache (to prime, so we could use a functional interface)
// - Database dropping support for auto-schema-tooling (again, could be functional interface - in fact if ultimately is in terms of how we do that)
// - Creation of named entity-graphs
// - Access to IdentifierGenerators, though we could manage this as part of the DomainMetamodel (and logically maybe that is where it belongs)
// - SessionFactoryOptions
// - BytecodeProvider
// - JpaCompliance
//
// Ultimately the idea here is to build the `InflightRuntimeMetamodel` and pass that along to
// the JpaMetamodel and DomainMetamodel. At a high-level; the details may be to instead
// build the `InflightRuntimeMetamodel` and use the collected information individually to
// each - e.g.:
// ````
// new JpaMetamodel(
// inflightRuntimeMetamodel.getJpaEntityTypes(),
// inflightRuntimeMetamodel.getJpaEmbeddableTypes,
// ...
// );
// ````
//
// ^^ Possibly account for either, e.g.:
// ````
// class JpaMetamodelImpl implements JpaMetamodel {
// static JpaMetamodelImpl create(
// InflightRuntimeMetamodel inflightRuntimeMetamodel,
// ... ) {
// return new JpaMetamodel(
// inflightRuntimeMetamodel.getJpaEntityTypes(),
// inflightRuntimeMetamodel.getJpaEmbeddableTypes,
// ...
// );
// }
// }
// ````
/**
* Perform the runtime metamodel creation based on the information obtained during
* the first phase of booting, returning the
*/
public static MetamodelImplementor execute(
SessionFactoryImplementor sessionFactory,
BootstrapContext bootstrapContext,
MetadataBuildingContext metadataBuildingContext,
MetadataImplementor bootMetamodel) {
return new RuntimeModelCreationProcess( sessionFactory, bootstrapContext, metadataBuildingContext ).execute();
}
private final SessionFactoryImplementor sessionFactory;
private final BootstrapContext bootstrapContext;
private final MetadataBuildingContext metadataBuildingContext;
public RuntimeModelCreationProcess(
SessionFactoryImplementor sessionFactory,
BootstrapContext bootstrapContext,
MetadataBuildingContext metadataBuildingContext) {
this.sessionFactory = sessionFactory;
this.bootstrapContext = bootstrapContext;
this.metadataBuildingContext = metadataBuildingContext;
}
public MetamodelImplementor execute() {
final InflightRuntimeMetamodel inflightRuntimeMetamodel = new InflightRuntimeMetamodel( bootstrapContext.getTypeConfiguration() );
throw new NotYetImplementedFor6Exception();
}
}

View File

@ -302,7 +302,7 @@ public class AttributeFactory {
PersistentClass persistentClass =
context.getPersistentClassHostingProperties( (MappedSuperclassTypeImpl<?>) ownerType );
return context.getMetamodel()
.resolveEntityPersister( persistentClass.getClassName() )
.findEntityDescriptor( persistentClass.getClassName() )
.getEntityMetamodel();
}
else {

View File

@ -91,7 +91,6 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
// 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<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -160,7 +159,6 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
public void initialize(
MetadataImplementor mappingMetadata,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) {
this.imports.putAll( mappingMetadata.getImports() );
primeSecondLevelCacheRegions( mappingMetadata );
@ -405,7 +403,7 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
}
@Override
public EntityPersister resolveEntityPersister(Object entity) {
public EntityPersister determineEntityPersister(Object entity) {
return findEntityDescriptor(entity.getClass());
}
@ -511,32 +509,6 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
return getJpaMetamodel().entity( entityName );
}
@Override
public String getImportedClassName(String className) {
String result = imports.get( className );
if ( result == null ) {
try {
sessionFactory.getServiceRegistry().getService( ClassLoaderService.class ).classForName( className );
imports.put( className, className );
return className;
}
catch (ClassLoadingException cnfe) {
imports.put( className, INVALID_IMPORT );
return null;
}
}
else {
// explicitly check for same instance
//noinspection StringEquality
if ( result == INVALID_IMPORT ) {
return null;
}
else {
return result;
}
}
}
@Override
public String[] getImplementors(String className) throws MappingException {
// computeIfAbsent() can be a contention point and we expect all the values to be in the map at some point so
@ -606,10 +578,6 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
return entityPersister;
}
public String getImportedName(String name){
return imports.get( name );
}
@Override
public void visitCollectionDescriptors(Consumer<CollectionPersister> action){
collectionPersisterMap.values().forEach( action );

View File

@ -65,17 +65,17 @@ public class JpaMetamodelImpl implements JpaMetamodel {
private final Map<String, EntityDomainType<?>> entityDescriptorMap = new ConcurrentHashMap<>();
private final Map<Class, EntityDomainType<?>> strictEntityDescriptorMap = new ConcurrentHashMap<>();
private final Map<Class<?>, MappedSuperclassType<?>> mappedSuperclassTypeMap = new ConcurrentHashMap<>();
private final Map<Class, EmbeddableDomainType<?>> embeddableDescriptorMap = new ConcurrentHashMap<>();
private final Set<EmbeddableDomainType<?>> embeddableDescriptors = new CopyOnWriteArraySet<>();
private final Map<Class, SqmPolymorphicRootDescriptor<?>> polymorphicEntityReferenceMap = new ConcurrentHashMap<>();
private final Map<String, String> nameToImportNameMap = new ConcurrentHashMap<>();
private final transient Map<String, RootGraphImplementor> entityGraphMap = new ConcurrentHashMap<>();
private final Map<Class, SqmPolymorphicRootDescriptor<?>> polymorphicEntityReferenceMap = new ConcurrentHashMap<>();
public JpaMetamodelImpl(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
@ -85,8 +85,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
MetadataImplementor mappingMetadata,
SqmCriteriaNodeBuilder criteriaBuilder,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting
) {
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting) {
if ( jpaMetaModelPopulationSetting != JpaMetaModelPopulationSetting.DISABLED ) {
MetadataContext context = new MetadataContext(
metamodel,
@ -104,14 +103,16 @@ public class JpaMetamodelImpl implements JpaMetamodel {
context.wrapUp();
strictEntityDescriptorMap.putAll( context.getEntityTypeMap() );
this.embeddableDescriptors.addAll( context.getEmbeddableTypeSet() );
for ( EmbeddableDomainType<?> embeddable : embeddableDescriptors ) {
this.embeddableDescriptorMap.put( embeddable.getJavaType(), embeddable );
}
this.nameToImportNameMap.putAll( mappingMetadata.getImports() );
this.strictEntityDescriptorMap.putAll( context.getEntityTypeMap() );
this.entityDescriptorMap.putAll( context.getEntityTypesByEntityName() );
this.mappedSuperclassTypeMap.putAll( context.getMappedSuperclassTypeMap() );
for ( EmbeddableDomainType<?> embeddable : context.getEmbeddableTypeSet() ) {
this.embeddableDescriptorMap.put( embeddable.getJavaType(), embeddable );
}
applyNamedEntityGraphs( mappingMetadata.getNamedEntityGraphs().values() );
}
}
@ -297,6 +298,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
@Override
public <X> EntityDomainType<X> entity(String entityName) {
//noinspection unchecked
return (EntityDomainType) entityDescriptorMap.get( entityName );
}
@ -321,6 +323,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
}
@Override
@SuppressWarnings("unchecked")
public void visitManagedTypes(Consumer<ManagedDomainType<?>> action) {
visitEntityTypes( (Consumer) action );
visitEmbeddables( (Consumer) action );
@ -334,16 +337,18 @@ public class JpaMetamodelImpl implements JpaMetamodel {
@Override
public void visitRootEntityTypes(Consumer<EntityDomainType<?>> action) {
entityDescriptorMap.values().forEach( entityDomainType -> {
if ( entityDomainType.getSuperType() == null ) {
action.accept( entityDomainType );
}
} );
entityDescriptorMap.values().forEach(
entityDomainType -> {
if ( entityDomainType.getSuperType() == null ) {
action.accept( entityDomainType );
}
}
);
}
@Override
public void visitEmbeddables(Consumer<EmbeddableDomainType<?>> action) {
embeddableDescriptors.forEach( action );
embeddableDescriptorMap.values().forEach( action );
}
@Override
@ -358,6 +363,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
if ( type == null ) {
throw new IllegalArgumentException( "Not a managed type: " + cls );
}
//noinspection unchecked
return (ManagedDomainType<X>) type;
}
@ -367,6 +373,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
if ( entityType == null ) {
throw new IllegalArgumentException( "Not an entity: " + cls );
}
//noinspection unchecked
return (EntityDomainType<X>) entityType;
}
@ -376,18 +383,19 @@ public class JpaMetamodelImpl implements JpaMetamodel {
if ( embeddableType == null ) {
throw new IllegalArgumentException( "Not an embeddable: " + cls );
}
//noinspection unchecked
return (EmbeddableDomainType<X>) embeddableType;
}
@Override
public Set<ManagedType<?>> getManagedTypes() {
final int setSize = CollectionHelper.determineProperSizing(
entityDescriptorMap.size() + mappedSuperclassTypeMap.size() + embeddableDescriptors.size()
entityDescriptorMap.size() + mappedSuperclassTypeMap.size() + embeddableDescriptorMap.size()
);
final Set<ManagedType<?>> managedTypes = new HashSet<>( setSize );
managedTypes.addAll( entityDescriptorMap.values() );
managedTypes.addAll( mappedSuperclassTypeMap.values() );
managedTypes.addAll( embeddableDescriptors );
managedTypes.addAll( embeddableDescriptorMap.values() );
return managedTypes;
}
@ -398,7 +406,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
@Override
public Set<EmbeddableType<?>> getEmbeddables() {
return new HashSet<>( embeddableDescriptors );
return new HashSet<>( embeddableDescriptorMap.values() );
}
@Override
@ -415,6 +423,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
@Override
public <T> RootGraphImplementor<T> findEntityGraphByName(String name) {
//noinspection unchecked
return entityGraphMap.get( name );
}
@ -428,12 +437,14 @@ public class JpaMetamodelImpl implements JpaMetamodel {
final List<RootGraphImplementor<? super T>> results = new ArrayList<>();
for ( EntityGraph entityGraph : entityGraphMap.values() ) {
if ( !RootGraphImplementor.class.isInstance( entityGraph ) ) {
if ( !(entityGraph instanceof RootGraphImplementor) ) {
continue;
}
final RootGraphImplementor egi = (RootGraphImplementor) entityGraph;
//noinspection unchecked
if ( egi.appliesTo( entityType ) ) {
//noinspection unchecked
results.add( egi );
}
}

View File

@ -24,31 +24,33 @@ import org.hibernate.type.spi.TypeConfiguration;
* @author Steve Ebersole
*/
public interface DomainMetamodel {
TypeConfiguration getTypeConfiguration();
JpaMetamodel getJpaMetamodel();
default EntityPersister resolveEntityPersister(EntityDomainType domainType) {
return findEntityDescriptor( domainType.getHibernateEntityName() );
default TypeConfiguration getTypeConfiguration() {
return getJpaMetamodel().getTypeConfiguration();
}
EntityPersister resolveEntityPersister(Object entity);
/**
* Given an (assumed) entity instance, determine its descriptor
*
* @see org.hibernate.EntityNameResolver
*/
EntityPersister determineEntityPersister(Object entity);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Entity descriptors
/**
* Given a JPA entity domain type, get the associated Hibernate entity descriptor
*/
default EntityPersister resolveEntityDescriptor(EntityDomainType<?> entityDomainType){
return resolveEntityPersister( entityDomainType );
}
/**
* Visit all entity mapping descriptors defined in the model
*/
void visitEntityDescriptors(Consumer<EntityPersister> action);
/**
* Given a JPA entity domain type, get the associated Hibernate entity descriptor
*/
EntityPersister resolveEntityDescriptor(EntityDomainType<?> entityDomainType);
/**
* Get an entity mapping descriptor based on its Hibernate entity-name
*

View File

@ -28,9 +28,11 @@ import org.hibernate.type.spi.TypeConfiguration;
* Hibernate extension to the JPA {@link Metamodel} contract
*
* @author Steve Ebersole
*
* @deprecated (since 6.0) - Prefer {@link org.hibernate.metamodel.spi.DomainMetamodel}
*/
@Deprecated
public interface MetamodelImplementor extends Metamodel {
public interface MetamodelImplementor extends DomainMetamodel, Metamodel {
/**
* Access to the TypeConfiguration in effect for this SessionFactory/Metamodel
*

View File

@ -592,7 +592,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
if ( ctx.dynamicInstantiationTarget().MAP() != null ) {
if ( mapJavaTypeDescriptor == null ) {
mapJavaTypeDescriptor = creationContext.getDomainModel()
mapJavaTypeDescriptor = creationContext.getJpaMetamodel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Map.class );
@ -604,7 +604,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
}
else if ( ctx.dynamicInstantiationTarget().LIST() != null ) {
if ( listJavaTypeDescriptor == null ) {
listJavaTypeDescriptor = creationContext.getDomainModel()
listJavaTypeDescriptor = creationContext.getJpaMetamodel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( List.class );
@ -618,7 +618,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final String className = ctx.dynamicInstantiationTarget().dotIdentifierSequence().getText();
try {
final Class<?> targetJavaType = classForName( className );
final JavaTypeDescriptor jtd = creationContext.getDomainModel()
final JavaTypeDescriptor jtd = creationContext.getJpaMetamodel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.resolveDescriptor( targetJavaType );
@ -836,7 +836,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
log.debugf( "Attempting to resolve path [%s] as entity reference...", entityName );
EntityDomainType reference = null;
try {
reference = creationContext.getDomainModel().entity( entityName );
reference = creationContext.getJpaMetamodel().entity( entityName );
}
catch (Exception ignore) {
}
@ -889,7 +889,9 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
log.debugf( "Handling root path - %s", name );
final EntityDomainType entityDescriptor = getCreationContext().getDomainModel().resolveHqlEntityReference( name );
final EntityDomainType entityDescriptor = getCreationContext().getJpaMetamodel().resolveHqlEntityReference(
name
);
if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) {
if ( getCreationOptions().useStrictJpaCompliance() ) {
@ -965,7 +967,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
SqmTreeCreationLogger.LOGGER.debugf( "Handling root path - %s", name );
final EntityDomainType entityDescriptor = getCreationContext().getDomainModel().resolveHqlEntityReference( name );
final EntityDomainType entityDescriptor = getCreationContext().getJpaMetamodel().resolveHqlEntityReference( name );
if ( entityDescriptor instanceof SqmPolymorphicRootDescriptor ) {
throw new SemanticException( "Unmapped polymorphic reference cannot be used as a CROSS JOIN target" );
@ -1339,7 +1341,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
BinaryArithmeticOperator.ADD,
(SqmExpression) ctx.expression( 0 ).accept( this ),
(SqmExpression) ctx.expression( 1 ).accept( this ),
creationContext.getDomainModel(),
creationContext.getJpaMetamodel(),
creationContext.getNodeBuilder()
);
}
@ -1354,7 +1356,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
BinaryArithmeticOperator.SUBTRACT,
(SqmExpression) ctx.expression( 0 ).accept( this ),
(SqmExpression) ctx.expression( 1 ).accept( this ),
creationContext.getDomainModel(),
creationContext.getJpaMetamodel(),
creationContext.getNodeBuilder()
);
}
@ -1369,7 +1371,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
BinaryArithmeticOperator.MULTIPLY,
(SqmExpression) ctx.expression( 0 ).accept( this ),
(SqmExpression) ctx.expression( 1 ).accept( this ),
creationContext.getDomainModel(),
creationContext.getJpaMetamodel(),
creationContext.getNodeBuilder()
);
}
@ -1385,7 +1387,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
BinaryArithmeticOperator.DIVIDE,
(SqmExpression) ctx.expression( 0 ).accept( this ),
(SqmExpression) ctx.expression( 1 ).accept( this ),
creationContext.getDomainModel(),
creationContext.getJpaMetamodel(),
creationContext.getNodeBuilder()
);
}
@ -1790,7 +1792,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
private <J> BasicDomainType<J> resolveExpressableTypeBasic(Class<J> javaType) {
//noinspection unchecked
return creationContext.getDomainModel().getTypeConfiguration().standardBasicTypeForJavaType( javaType );
return creationContext.getJpaMetamodel().getTypeConfiguration().standardBasicTypeForJavaType( javaType );
}
@Override
@ -2736,7 +2738,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
public SqmPath<?> visitTreatedNavigablePath(HqlParser.TreatedNavigablePathContext ctx) {
final SqmPath<?> sqmPath = consumeManagedTypeReference( ctx.path() );
final String treatTargetName = ctx.dotIdentifierSequence().getText();
final EntityDomainType<?> treatTarget = getCreationContext().getDomainModel().entity( treatTargetName );
final EntityDomainType<?> treatTarget = getCreationContext().getJpaMetamodel().entity( treatTargetName );
SqmPath<?> result = resolveTreatedPath( sqmPath, treatTarget );

View File

@ -22,13 +22,13 @@ public interface SqmCreationContext {
/**
* Access to the domain model metadata
*/
JpaMetamodel getDomainModel();
JpaMetamodel getJpaMetamodel();
/**
* Access to the ServiceRegistry for the context
*/
default ServiceRegistry getServiceRegistry() {
return getDomainModel().getServiceRegistry();
return getJpaMetamodel().getServiceRegistry();
}
QueryEngine getQueryEngine();

View File

@ -15,6 +15,8 @@ import java.time.LocalTime;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.produce.spi.SqmCreationState;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor;
/**
* @author Steve Ebersole
@ -22,12 +24,12 @@ import org.hibernate.query.sqm.produce.spi.SqmCreationState;
public class LiteralHelper {
public static SqmLiteral<Timestamp> timestampLiteralFrom(String literalText, SqmCreationState creationState) {
final Timestamp literal = Timestamp.valueOf(
LocalDateTime.from( JdbcTimestampJavaDescriptor.FORMATTER.parse( literalText ) )
LocalDateTime.from( JdbcTimestampTypeDescriptor.FORMATTER.parse( literalText ) )
);
return new SqmLiteral<>(
literal,
creationState.getCreationContext().getDomainModel().getTypeConfiguration().getBasicTypeRegistry().getBasicType( Timestamp.class ),
creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration().standardBasicTypeForJavaType( Timestamp.class ),
creationState.getCreationContext().getQueryEngine().getCriteriaBuilder()
);
}
@ -43,7 +45,7 @@ public class LiteralHelper {
public static SqmLiteral<Integer> integerLiteral(int value, QueryEngine queryEngine) {
return new SqmLiteral<>(
value,
StandardSpiBasicTypes.INTEGER,
StandardBasicTypes.INTEGER,
queryEngine.getCriteriaBuilder()
);
}
@ -54,7 +56,7 @@ public class LiteralHelper {
return new SqmLiteral<>(
literal,
creationState.getCreationContext().getDomainModel().getTypeConfiguration().getBasicTypeRegistry().getBasicType( Date.class ),
creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration().getBasicTypeRegistry().getBasicType( Date.class ),
creationState.getCreationContext().getQueryEngine().getCriteriaBuilder()
);
}
@ -65,7 +67,7 @@ public class LiteralHelper {
return new SqmLiteral<>(
literal,
creationState.getCreationContext().getDomainModel().getTypeConfiguration().getBasicTypeRegistry().getBasicType( Time.class ),
creationState.getCreationContext().getJpaMetamodel().getTypeConfiguration().getBasicTypeRegistry().getBasicType( Time.class ),
creationState.getCreationContext().getQueryEngine().getCriteriaBuilder()
);
}