Some pre-work for embeddable instantiator work.

This commit is contained in:
Steve Ebersole 2021-11-11 16:49:59 -06:00
parent db12d5a17a
commit 7b1201d542
17 changed files with 192 additions and 298 deletions

View File

@ -11,10 +11,6 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Iterator;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.Type;
import org.hibernate.AssertionFailure;
import org.hibernate.internal.EntityManagerMessageLogger;
@ -29,6 +25,7 @@ import org.hibernate.mapping.Property;
import org.hibernate.mapping.Value;
import org.hibernate.metamodel.AttributeClassification;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
@ -52,6 +49,12 @@ import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.EntityType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.CompositeTypeImplementor;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.Type;
/**
* A factory for building {@link Attribute} instances. Exposes 3 main services for building<ol>
@ -231,21 +234,16 @@ public class AttributeFactory {
final Component component = (Component) typeContext.getHibernateValue();
final EmbeddableTypeImpl<Y> embeddableType;
final EmbeddableRepresentationStrategy representationStrategy = context.getTypeConfiguration()
.getMetadataBuildingContext()
.getBuildingOptions()
.getManagedTypeRepresentationResolver()
.resolveStrategy( component, context.getRuntimeModelCreationContext() );
if ( component.isDynamic() ) {
final JavaType javaTypeDescriptor = context.getJavaTypeDescriptorRegistry().getDescriptor( Map.class );
embeddableType = new EmbeddableTypeImpl<>(
javaTypeDescriptor,
representationStrategy,
true,
context.getJpaMetamodel()
);
context.registerComponentByEmbeddable( embeddableType, component );
}
else {
// we should have a non-dynamic embeddable
@ -263,7 +261,6 @@ public class AttributeFactory {
embeddableType = new EmbeddableTypeImpl<>(
javaTypeDescriptor,
representationStrategy,
false,
context.getJpaMetamodel()
);
@ -585,16 +582,23 @@ public class AttributeFactory {
private static final MemberResolver embeddedMemberResolver = (attributeContext, metadataContext) -> {
// the owner is an embeddable
final EmbeddableDomainType<?> ownerType = (EmbeddableDomainType) attributeContext.getOwnerType();
final EmbeddableDomainType<?> ownerType = (EmbeddableDomainType<?>) attributeContext.getOwnerType();
final Component ownerBootDescriptor = metadataContext.getEmbeddableBootDescriptor( ownerType );
if ( ownerType.getRepresentationStrategy().getMode() == RepresentationMode.MAP ) {
final CompositeTypeImplementor ownerComponentType = (CompositeTypeImplementor) ownerBootDescriptor.getType();
final EmbeddableValuedModelPart ownerMappingModelDescriptor = ownerComponentType.getMappingModelPart();
final EmbeddableRepresentationStrategy ownerRepStrategy = ownerMappingModelDescriptor
.getEmbeddableTypeDescriptor()
.getRepresentationStrategy();
if ( ownerRepStrategy.getMode() == RepresentationMode.MAP ) {
return new MapMember(
attributeContext.getPropertyMapping().getName(),
attributeContext.getPropertyMapping().getType().getReturnedClass()
);
}
else {
return ownerType.getRepresentationStrategy()
return ownerRepStrategy
.resolvePropertyAccess( attributeContext.getPropertyMapping() )
.getGetter()
.getMember();

View File

@ -6,10 +6,12 @@
*/
package org.hibernate.metamodel.internal;
import java.util.Map;
import java.util.function.Supplier;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Component;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
/**
@ -20,12 +22,24 @@ import org.hibernate.metamodel.spi.EmbeddableInstantiator;
public class EmbeddableInstantiatorDynamicMap
extends AbstractDynamicMapInstantiator
implements EmbeddableInstantiator {
public EmbeddableInstantiatorDynamicMap(Component bootDescriptor) {
private final Supplier<EmbeddableMappingType> runtimeDescriptorAccess;
public EmbeddableInstantiatorDynamicMap(
Component bootDescriptor,
Supplier<EmbeddableMappingType> runtimeDescriptorAccess) {
super( bootDescriptor.getRoleName() );
this.runtimeDescriptorAccess = runtimeDescriptorAccess;
}
@Override
public Object instantiate(Supplier<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
return generateDataMap();
final Map<?,?> dataMap = generateDataMap();
if ( valuesAccess != null ) {
final EmbeddableMappingType mappingType = runtimeDescriptorAccess.get();
mappingType.setPropertyValues( dataMap, valuesAccess.get() );
}
return dataMap;
}
}

View File

@ -10,12 +10,13 @@ import java.lang.reflect.Constructor;
import java.util.function.Supplier;
import org.hibernate.InstantiationException;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.Component;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.type.descriptor.java.JavaType;
@ -27,16 +28,16 @@ import org.hibernate.type.descriptor.java.JavaType;
public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator implements EmbeddableInstantiator {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiatorImpl.class );
private final Supplier<EmbeddableMappingType> embeddableMappingAccess;
private final Constructor<?> constructor;
public EmbeddableInstantiatorPojoStandard(
@SuppressWarnings("unused") Component bootDescriptor,
Supplier<EmbeddableMappingType> embeddableMappingAccess,
JavaType<?> javaTypeDescriptor) {
super( javaTypeDescriptor.getJavaTypeClass() );
constructor = resolveConstructor( javaTypeDescriptor.getJavaTypeClass() );
// todo (6.0) : add support for constructor value injection
this.embeddableMappingAccess = embeddableMappingAccess;
this.constructor = resolveConstructor( javaTypeDescriptor.getJavaTypeClass() );
}
protected static Constructor<?> resolveConstructor(Class<?> mappedPojoClass) {
@ -55,16 +56,27 @@ public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator
if ( isAbstract() ) {
throw new InstantiationException( "Cannot instantiate abstract class or interface: ", getMappedPojoClass() );
}
else if ( constructor == null ) {
if ( constructor == null ) {
throw new InstantiationException( "No default constructor for embeddable: ", getMappedPojoClass() );
}
else {
try {
return constructor.newInstance( (Object[]) null );
if ( valuesAccess != null ) {
if ( constructor.getParameterTypes().length > 0 ) {
// constructor injection
throw new NotYetImplementedFor6Exception( "Constructor injection for embeddables not yet implemented" );
}
catch ( Exception e ) {
throw new InstantiationException( "Could not instantiate entity: ", getMappedPojoClass(), e );
}
try {
final Object instance = constructor.newInstance();
if ( valuesAccess != null ) {
embeddableMappingAccess.get().setPropertyValues( instance, valuesAccess.get() );
}
return instance;
}
catch ( Exception e ) {
throw new InstantiationException( "Could not instantiate embeddable: ", getMappedPojoClass(), e );
}
}
}

View File

@ -7,11 +7,13 @@
package org.hibernate.metamodel.internal;
import java.util.Map;
import java.util.function.Supplier;
import org.hibernate.bytecode.spi.ReflectionOptimizer;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
@ -28,9 +30,10 @@ public class EmbeddableRepresentationStrategyMap implements EmbeddableRepresenta
public EmbeddableRepresentationStrategyMap(
Component bootDescriptor,
Supplier<EmbeddableMappingType> runtimeDescriptorAccess,
RuntimeModelCreationContext creationContext) {
this.mapJtd = creationContext.getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class );
this.instantiator = new EmbeddableInstantiatorDynamicMap( bootDescriptor );
this.instantiator = new EmbeddableInstantiatorDynamicMap( bootDescriptor, runtimeDescriptorAccess );
}
@Override

View File

@ -7,6 +7,7 @@
package org.hibernate.metamodel.internal;
import java.util.Locale;
import java.util.function.Supplier;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
@ -20,6 +21,7 @@ import org.hibernate.mapping.Component;
import org.hibernate.mapping.IndexBackref;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.spi.EmbeddableInstantiator;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
@ -39,6 +41,7 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
public EmbeddableRepresentationStrategyPojo(
Component bootDescriptor,
Supplier<EmbeddableMappingType> runtimeDescriptorAccess,
RuntimeModelCreationContext creationContext) {
super(
bootDescriptor,
@ -64,10 +67,10 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
false
);
this.instantiator = determineInstantiator( bootDescriptor );
this.instantiator = determineInstantiator( runtimeDescriptorAccess );
}
private EmbeddableInstantiator determineInstantiator(Component bootDescriptor) {
private EmbeddableInstantiator determineInstantiator(Supplier<EmbeddableMappingType> runtimeDescriptorAccess) {
if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) {
final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer();
return new EmbeddableInstantiatorPojoOptimized(
@ -77,7 +80,7 @@ public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepr
}
return new EmbeddableInstantiatorPojoStandard(
bootDescriptor,
runtimeDescriptorAccess,
getEmbeddableJavaTypeDescriptor()
);
}

View File

@ -54,6 +54,7 @@ import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.CompositeType;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.CompositeTypeImplementor;
/**
* @author Steve Ebersole
@ -112,12 +113,14 @@ public class EntityRepresentationStrategyPojoStandard implements EntityRepresent
if ( bootDescriptor.getIdentifierMapper() != null ) {
mapsIdRepresentationStrategy = new EmbeddableRepresentationStrategyPojo(
bootDescriptor.getIdentifierMapper(),
() -> ( ( CompositeTypeImplementor) bootDescriptor.getIdentifierMapper().getType() ).getMappingModelPart().getEmbeddableTypeDescriptor(),
creationContext
);
}
else if ( bootDescriptorIdentifier != null ) {
mapsIdRepresentationStrategy = new EmbeddableRepresentationStrategyPojo(
(Component) bootDescriptorIdentifier,
() -> ( ( CompositeTypeImplementor) bootDescriptor.getIdentifierMapper().getType() ).getMappingModelPart().getEmbeddableTypeDescriptor(),
creationContext
);
}

View File

@ -7,9 +7,12 @@
package org.hibernate.metamodel.internal;
import java.util.function.Supplier;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
@ -58,6 +61,7 @@ public class ManagedTypeRepresentationResolverStandard implements ManagedTypeRep
@Override
public EmbeddableRepresentationStrategy resolveStrategy(
Component bootDescriptor,
Supplier<EmbeddableMappingType> runtimeDescriptorAccess,
RuntimeModelCreationContext creationContext) {
// RepresentationMode representation = bootDescriptor.getExplicitRepresentationMode();
RepresentationMode representation = null;
@ -71,7 +75,7 @@ public class ManagedTypeRepresentationResolverStandard implements ManagedTypeRep
}
if ( representation == RepresentationMode.MAP ) {
return new EmbeddableRepresentationStrategyMap( bootDescriptor, creationContext );
return new EmbeddableRepresentationStrategyMap( bootDescriptor, runtimeDescriptorAccess, creationContext );
}
else {
// todo (6.0) : fix this
@ -80,7 +84,7 @@ public class ManagedTypeRepresentationResolverStandard implements ManagedTypeRep
//
// instead, resolve ReflectionOptimizer once - here - and pass along to
// StandardPojoRepresentationStrategy
return new EmbeddableRepresentationStrategyPojo( bootDescriptor, creationContext );
return new EmbeddableRepresentationStrategyPojo( bootDescriptor, runtimeDescriptorAccess, creationContext );
}
}
}

View File

@ -15,14 +15,11 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.IdentifiableType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type;
import org.hibernate.AssertionFailure;
import org.hibernate.Internal;
import org.hibernate.MappingException;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.internal.util.ReflectHelper;
@ -48,12 +45,16 @@ import org.hibernate.metamodel.model.domain.internal.EmbeddableTypeImpl;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.IdentifiableType;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type;
/**
* Defines a context for storing information during the building of the {@link MappingMetamodelImpl}.
* <p/>
@ -101,15 +102,16 @@ public class MetadataContext {
public MetadataContext(
JpaMetamodel jpaMetamodel,
RuntimeModelCreationContext runtimeModelCreationContext,
Set<MappedSuperclass> mappedSuperclasses,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting) {
MappingMetamodel mappingMetamodel,
MetadataImplementor bootMetamodel,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting,
RuntimeModelCreationContext runtimeModelCreationContext) {
this.jpaMetamodel = jpaMetamodel;
this.runtimeModelCreationContext = runtimeModelCreationContext;
this.metamodel = runtimeModelCreationContext.getSessionFactory().getMetamodel();
this.knownMappedSuperclasses = mappedSuperclasses;
this.metamodel = mappingMetamodel;
this.knownMappedSuperclasses = bootMetamodel.getMappedSuperclassMappingsCopy();
this.typeConfiguration = runtimeModelCreationContext.getTypeConfiguration();
this.jpaStaticMetaModelPopulationSetting = jpaStaticMetaModelPopulationSetting;
this.runtimeModelCreationContext = runtimeModelCreationContext;
}
public RuntimeModelCreationContext getRuntimeModelCreationContext() {
@ -177,11 +179,22 @@ public class MetadataContext {
assert embeddableType.getJavaType() != null;
assert ! Map.class.isAssignableFrom( embeddableType.getJavaType() );
embeddablesToProcess.computeIfAbsent( embeddableType.getJavaType(), k -> new ArrayList<>( 1 ) )
.add( embeddableType );
embeddablesToProcess
.computeIfAbsent( embeddableType.getJavaType(), k -> new ArrayList<>( 1 ) )
.add( embeddableType );
registerComponentByEmbeddable( embeddableType, bootDescriptor );
}
public void registerComponentByEmbeddable(
EmbeddableDomainType<?> embeddableType,
Component bootDescriptor) {
componentByEmbeddable.put( embeddableType, bootDescriptor );
}
public Component getEmbeddableBootDescriptor(EmbeddableDomainType<?> embeddableType) {
return componentByEmbeddable.get( embeddableType );
}
public void registerMappedSuperclassType(
MappedSuperclass mappedSuperclass,
MappedSuperclassDomainType<?> mappedSuperclassType) {
@ -428,15 +441,8 @@ public class MetadataContext {
final Class<?> componentClass = identifier.getComponentClass();
final JavaType<?> javaTypeDescriptor = registry.resolveManagedTypeDescriptor( componentClass );
final EmbeddableRepresentationStrategy representationStrategy = getTypeConfiguration()
.getMetadataBuildingContext()
.getBuildingOptions()
.getManagedTypeRepresentationResolver()
.resolveStrategy( idClass, getRuntimeModelCreationContext() );
final EmbeddableTypeImpl<?> embeddableType = new EmbeddableTypeImpl<>(
javaTypeDescriptor,
representationStrategy,
false,
getJpaMetamodel()
);

View File

@ -92,15 +92,10 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
MappingModelCreationProcess creationProcess) {
final RuntimeModelCreationContext creationContext = creationProcess.getCreationContext();
final EmbeddableRepresentationStrategy representationStrategy = creationContext.getBootstrapContext()
.getRepresentationStrategySelector()
.resolveStrategy( bootDescriptor, creationContext );
final EmbeddableMappingType mappingType = new EmbeddableMappingType(
bootDescriptor,
representationStrategy,
embeddedPartBuilder,
creationContext.getSessionFactory()
creationContext
);
if ( compositeType instanceof CompositeTypeImplementor ) {
@ -157,12 +152,15 @@ public class EmbeddableMappingType implements ManagedMappingType, SelectableMapp
private EmbeddableMappingType(
Component bootDescriptor,
EmbeddableRepresentationStrategy representationStrategy,
Function<EmbeddableMappingType, EmbeddableValuedModelPart> embeddedPartBuilder,
SessionFactoryImplementor sessionFactory) {
RuntimeModelCreationContext creationContext) {
this.representationStrategy = creationContext
.getBootstrapContext()
.getRepresentationStrategySelector()
.resolveStrategy( bootDescriptor, () -> this, creationContext );
this.embeddableJtd = representationStrategy.getMappedJavaTypeDescriptor();
this.representationStrategy = representationStrategy;
this.sessionFactory = sessionFactory;
this.sessionFactory = creationContext.getSessionFactory();
this.valueMapping = embeddedPartBuilder.apply( this );

View File

@ -8,8 +8,6 @@ package org.hibernate.metamodel.model.domain;
import jakarta.persistence.metamodel.EmbeddableType;
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
/**
* Hibernate extension to the JPA {@link EmbeddableType} contract.
*
@ -19,5 +17,4 @@ import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
* @author Steve Ebersole
*/
public interface EmbeddableDomainType<J> extends ManagedDomainType<J>, EmbeddableType<J>, AllowableParameterType<J> {
ManagedTypeRepresentationStrategy getRepresentationStrategy();
}

View File

@ -7,16 +7,12 @@
package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import java.util.Map;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.graph.internal.SubGraphImpl;
import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.metamodel.model.domain.AbstractManagedType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy;
import org.hibernate.metamodel.spi.ManagedTypeRepresentationStrategy;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -31,40 +27,15 @@ public class EmbeddableTypeImpl<J>
implements EmbeddableDomainType<J>, Serializable {
private final boolean isDynamic;
private final EmbeddableRepresentationStrategy representationStrategy;
public EmbeddableTypeImpl(
JavaType<J> javaTypeDescriptor,
EmbeddableRepresentationStrategy representationStrategy,
boolean isDynamic,
JpaMetamodel domainMetamodel) {
super( javaTypeDescriptor.getJavaType().getTypeName(), javaTypeDescriptor, null, domainMetamodel );
this.representationStrategy = representationStrategy;
this.isDynamic = isDynamic;
}
public EmbeddableTypeImpl(
String name,
JpaMetamodel domainMetamodel) {
//noinspection unchecked
super(
name,
(JavaType) domainMetamodel.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Map.class ),
null,
domainMetamodel
);
// todo (6.0) : need ManagedTypeRepresentationStrategy impls
throw new NotYetImplementedFor6Exception( getClass() );
}
@Override
public ManagedTypeRepresentationStrategy getRepresentationStrategy() {
return representationStrategy;
}
@Override
public PersistenceType getPersistenceType() {
return PersistenceType.EMBEDDABLE;

View File

@ -43,6 +43,7 @@ import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.spi.JpaCompliance;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.MetadataContext;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
@ -488,6 +489,7 @@ public class JpaMetamodelImpl implements JpaMetamodel, Serializable {
public void processJpa(
MetadataImplementor bootMetamodel,
MappingMetamodel mappingMetamodel,
Map<Class, String> entityProxyInterfaceMap,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting,
Collection<NamedEntityGraphDefinition> namedEntityGraphDefinitions,
@ -495,62 +497,63 @@ public class JpaMetamodelImpl implements JpaMetamodel, Serializable {
bootMetamodel.getImports().forEach( ( k, v ) -> this.nameToImportMap.put( k, new ImportInfo<>( v, null ) ) );
this.entityProxyInterfaceMap.putAll( entityProxyInterfaceMap );
// todo (6.0) : I believe there should be a distinction here between building the JPA metamodel and pushing that metamodel to the `X_` model
// - JpaStaticMetaModelPopulationSetting is meant to control the latter part - populating the `X_` model
if ( jpaStaticMetaModelPopulationSetting != JpaStaticMetaModelPopulationSetting.DISABLED ) {
MetadataContext context = new MetadataContext(
this,
runtimeModelCreationContext,
bootMetamodel.getMappedSuperclassMappingsCopy(),
jpaStaticMetaModelPopulationSetting
);
final MetadataContext context = new MetadataContext(
this,
mappingMetamodel,
bootMetamodel,
jpaStaticMetaModelPopulationSetting,
runtimeModelCreationContext
);
for ( PersistentClass entityBinding : bootMetamodel.getEntityBindings() ) {
locateOrBuildEntityType( entityBinding, context, typeConfiguration );
}
handleUnusedMappedSuperclasses( context, typeConfiguration );
context.wrapUp();
for ( PersistentClass entityBinding : bootMetamodel.getEntityBindings() ) {
locateOrBuildEntityType( entityBinding, context, typeConfiguration );
}
handleUnusedMappedSuperclasses( context, typeConfiguration );
this.jpaEntityTypeMap.putAll( context.getEntityTypesByEntityName() );
this.jpaMappedSuperclassTypeMap.putAll( context.getMappedSuperclassTypeMap() );
context.wrapUp();
for ( EmbeddableDomainType<?> embeddable : context.getEmbeddableTypeSet() ) {
this.jpaEmbeddableDescriptorMap.put( embeddable.getJavaType(), embeddable );
}
Stream.concat(
context.getEntityTypesByEntityName().values().stream(),
Stream.concat(
context.getMappedSuperclassTypeMap().values().stream(),
context.getEmbeddableTypeSet().stream()
)
).forEach( managedDomainType -> {
managedDomainType.visitAttributes( persistentAttribute -> {
if ( persistentAttribute.getJavaType() != null && persistentAttribute.getJavaType().isEnum() ) {
@SuppressWarnings("unchecked")
Class<Enum<?>> enumClass = (Class<Enum<?>>) persistentAttribute.getJavaType();
Enum<?>[] enumConstants = enumClass.getEnumConstants();
for ( Enum<?> enumConstant : enumConstants ) {
String qualifiedEnumLiteral = enumConstant.getDeclaringClass()
.getSimpleName() + "." + enumConstant.name();
this.jpaEntityTypeMap.putAll( context.getEntityTypesByEntityName() );
this.jpaMappedSuperclassTypeMap.putAll( context.getMappedSuperclassTypeMap() );
this.allowedEnumLiteralTexts.computeIfAbsent(
enumConstant.name(),
k -> new ConcurrentHashMap<>()
).put( enumClass, enumConstant );
this.allowedEnumLiteralTexts.computeIfAbsent(
qualifiedEnumLiteral,
k -> new ConcurrentHashMap<>()
).put( enumClass, enumConstant );
}
}
} );
} );
for ( EmbeddableDomainType<?> embeddable : context.getEmbeddableTypeSet() ) {
this.jpaEmbeddableDescriptorMap.put( embeddable.getJavaType(), embeddable );
}
domainTypeStream( context ).forEach( (managedDomainType) -> managedDomainType.visitAttributes( persistentAttribute -> {
if ( persistentAttribute.getJavaType() != null && persistentAttribute.getJavaType().isEnum() ) {
@SuppressWarnings("unchecked")
Class<Enum<?>> enumClass = (Class<Enum<?>>) persistentAttribute.getJavaType();
Enum<?>[] enumConstants = enumClass.getEnumConstants();
for ( Enum<?> enumConstant : enumConstants ) {
String qualifiedEnumLiteral = enumConstant.getDeclaringClass()
.getSimpleName() + "." + enumConstant.name();
this.allowedEnumLiteralTexts.computeIfAbsent(
enumConstant.name(),
k -> new ConcurrentHashMap<>()
).put( enumClass, enumConstant );
this.allowedEnumLiteralTexts.computeIfAbsent(
qualifiedEnumLiteral,
k -> new ConcurrentHashMap<>()
).put( enumClass, enumConstant );
}
}
} ) );
applyNamedEntityGraphs( namedEntityGraphDefinitions );
}
private static Stream<ManagedDomainType<?>> domainTypeStream(MetadataContext context) {
return Stream.concat(
context.getEntityTypesByEntityName().values().stream(),
Stream.concat(
context.getMappedSuperclassTypeMap().values().stream(),
context.getEmbeddableTypeSet().stream()
)
);
}
private EntityDomainType<?> locateOrBuildEntityType(
PersistentClass persistentClass,
MetadataContext context,

View File

@ -233,6 +233,7 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
( (JpaMetamodelImpl) this.jpaMetamodel ).processJpa(
bootModel,
this,
entityProxyInterfaceMap,
jpaStaticMetaModelPopulationSetting,
bootModel.getNamedEntityGraphs().values(),

View File

@ -6,9 +6,12 @@
*/
package org.hibernate.metamodel.spi;
import java.util.function.Supplier;
import org.hibernate.Incubating;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.persister.entity.EntityPersister;
/**
@ -35,5 +38,6 @@ public interface ManagedTypeRepresentationResolver {
*/
EmbeddableRepresentationStrategy resolveStrategy(
Component bootDescriptor,
Supplier<EmbeddableMappingType> runtimeDescriptor,
RuntimeModelCreationContext creationContext);
}

View File

@ -151,7 +151,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
compositeInstance = embeddableTypeDescriptor
.getRepresentationStrategy()
.getInstantiator()
.instantiate( VALUE_ACCESS, rowProcessingState.getSession().getFactory() );
.instantiate( null, rowProcessingState.getSession().getFactory() );
}
EmbeddableLoadingLogger.INSTANCE.debugf(
@ -160,10 +160,6 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
);
}
private static Supplier<Object[]> VALUE_ACCESS = () -> {
throw new NotYetImplementedFor6Exception( "Constructor value injection for embeddables not yet implemented" );
};
@Override
public void initializeInstance(RowProcessingState rowProcessingState) {
@ -232,7 +228,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
Object target = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor()
.getRepresentationStrategy()
.getInstantiator()
.instantiate( VALUE_ACCESS, rowProcessingState.getSession().getFactory() );
.instantiate( null, rowProcessingState.getSession().getFactory() );
embeddedModelPartDescriptor.getEmbeddableTypeDescriptor().setPropertyValues(
target,
resolvedValues

View File

@ -1,150 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.intg.sqm;
import java.util.Collections;
import java.util.Optional;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.orm.test.jpa.JpaComplianceStub;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl;
import org.hibernate.metamodel.MappingMetamodel;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.criteria.ValueHandlingMode;
import org.hibernate.query.hql.HqlTranslator;
import org.hibernate.query.hql.internal.StandardHqlTranslator;
import org.hibernate.query.hql.spi.SqmCreationOptions;
import org.hibernate.query.internal.NamedObjectRepositoryImpl;
import org.hibernate.query.named.NamedObjectRepository;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.spi.SqmCreationContext;
import org.hibernate.query.sqm.tree.SqmStatement;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.DomainModelScope;
import org.hibernate.testing.orm.junit.FailureExpected;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
import org.junit.jupiter.api.Test;
/**
* Tests making sure that HQL queries can fully be translated without a SessionFactory.
*
* todo (6.0) : have a way to directly load these translations into the {@link NamedObjectRepository}
* directly. For example Quarkus could store its build-time translations and directly here during boot-strap of the SF
*
* @author Steve Ebersole
*/
@ServiceRegistry
@DomainModel( standardModels = StandardDomainModel.RETAIL )
public class HqlTranslationNoFactoryTests {
@Test
@FailureExpected( reason = "Building the JpaDomain")
public void testHqlTranslationNoSessionFactory(DomainModelScope modelScope, ServiceRegistryScope registryScope) {
final String hql = "select a from SalesAssociate a";
final HqlTranslator hqlTranslator = buildHqlTranslator( modelScope, registryScope );
final SqmStatement<?> sqmStatement = hqlTranslator.translate( hql );
assert sqmStatement != null;
}
private HqlTranslator buildHqlTranslator(DomainModelScope modelScope, ServiceRegistryScope registryScope) {
final MetadataImplementor bootModel = modelScope.getDomainModel();
final TypeConfiguration typeConfiguration = bootModel.getTypeConfiguration();
final JpaMetamodelImpl jpaMetamodel = new JpaMetamodelImpl( typeConfiguration, new JpaComplianceStub() );
// todo (6.0) (quarkus) : we should limit the type of the last argument here from `RuntimeModelCreationContext`
// which assumes access to SessionFactory
jpaMetamodel.processJpa(
bootModel,
Collections.emptyMap(),
JpaStaticMetaModelPopulationSetting.ENABLED,
Collections.emptyList(),
new RuntimeModelCreationContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
throw new UnsupportedOperationException( "SessionFactory not available" );
}
@Override
public BootstrapContext getBootstrapContext() {
return typeConfiguration.getMetadataBuildingContext().getBootstrapContext();
}
@Override
public MetadataImplementor getBootModel() {
return modelScope.getDomainModel();
}
@Override
public MappingMetamodel getDomainModel() {
throw new UnsupportedOperationException( "DomainMetamodel not available" );
}
}
);
Optional<QueryEngine> queryEngineAccess = Optional.empty();
// todo (6.0) (quarkus) : this circularity is problematic as well
// between `SqmCreationContext#getQueryEngine` and the `SqmCreationContext` passed to `#QueryEngine`
final SqmCreationContext sqmCreationContext = new SqmCreationContext() {
@Override
public JpaMetamodel getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public QueryEngine getQueryEngine() {
return queryEngineAccess.orElseThrow( () -> new RuntimeException( "Unexpected access to `SqmCreationContext#getQueryEngine`" ) );
}
};
// we don't want strict JPA query compliance
final SqmCreationOptions sqmCreationOptions = () -> false;
final QueryEngine queryEngine = new QueryEngine(
null,
null,
jpaMetamodel,
ValueHandlingMode.BIND,
ConfigurationHelper.getPreferredSqlTypeCodeForBoolean( registryScope.getRegistry() ),
// we don't want strict JPA query compliance
false,
new NamedObjectRepositoryImpl( Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap(), Collections.emptyMap() ),
// NativeQueryInterpreter
null,
// this is exclusively to build the SqmFunctionRegistry, maybe Quarkus should just build it directly and pass
registryScope.getRegistry().getService( JdbcServices.class ).getDialect(),
registryScope.getRegistry()
);
return new StandardHqlTranslator(
new SqmCreationContext() {
@Override
public JpaMetamodel getJpaMetamodel() {
return jpaMetamodel;
}
@Override
public QueryEngine getQueryEngine() {
return queryEngine;
}
},
sqmCreationOptions
);
}
}

View File

@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.orm.test.mapping.embeddable.strategy;
import org.hibernate.testing.orm.domain.gambit.EntityOfComposites;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
/**
* @author Steve Ebersole
*/
@DomainModel( annotatedClasses = EntityOfComposites.class )
@SessionFactory
public class FromAttributeFactoryTests {
@Test
public void simpleTest(SessionFactoryScope scope) {
scope.getSessionFactory().getRuntimeMetamodels();
}
}