Some pre-work for embeddable instantiator work.
This commit is contained in:
parent
db12d5a17a
commit
7b1201d542
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
if ( valuesAccess != null ) {
|
||||
if ( constructor.getParameterTypes().length > 0 ) {
|
||||
// constructor injection
|
||||
throw new NotYetImplementedFor6Exception( "Constructor injection for embeddables not yet implemented" );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return constructor.newInstance( (Object[]) null );
|
||||
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 entity: ", getMappedPojoClass(), e );
|
||||
}
|
||||
throw new InstantiationException( "Could not instantiate embeddable: ", getMappedPojoClass(), e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ) )
|
||||
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()
|
||||
);
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,16 +497,15 @@ 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(
|
||||
final MetadataContext context = new MetadataContext(
|
||||
this,
|
||||
runtimeModelCreationContext,
|
||||
bootMetamodel.getMappedSuperclassMappingsCopy(),
|
||||
jpaStaticMetaModelPopulationSetting
|
||||
mappingMetamodel,
|
||||
bootMetamodel,
|
||||
jpaStaticMetaModelPopulationSetting,
|
||||
runtimeModelCreationContext
|
||||
);
|
||||
|
||||
|
||||
for ( PersistentClass entityBinding : bootMetamodel.getEntityBindings() ) {
|
||||
locateOrBuildEntityType( entityBinding, context, typeConfiguration );
|
||||
}
|
||||
|
@ -518,14 +519,8 @@ public class JpaMetamodelImpl implements JpaMetamodel, Serializable {
|
|||
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 -> {
|
||||
|
||||
domainTypeStream( context ).forEach( (managedDomainType) -> managedDomainType.visitAttributes( persistentAttribute -> {
|
||||
if ( persistentAttribute.getJavaType() != null && persistentAttribute.getJavaType().isEnum() ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<Enum<?>> enumClass = (Class<Enum<?>>) persistentAttribute.getJavaType();
|
||||
|
@ -544,13 +539,21 @@ public class JpaMetamodelImpl implements JpaMetamodel, Serializable {
|
|||
).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,
|
||||
|
|
|
@ -233,6 +233,7 @@ public class MappingMetamodelImpl implements MappingMetamodel, MetamodelImplemen
|
|||
|
||||
( (JpaMetamodelImpl) this.jpaMetamodel ).processJpa(
|
||||
bootModel,
|
||||
this,
|
||||
entityProxyInterfaceMap,
|
||||
jpaStaticMetaModelPopulationSetting,
|
||||
bootModel.getNamedEntityGraphs().values(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue