From a6dc84e1feb3423bd691f1439ea14ae69c1ca6c1 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 24 Jun 2021 10:29:47 -0500 Subject: [PATCH] Work on Instantiator in preparation for composite-user-type work --- .../boot/internal/BootstrapContextImpl.java | 5 +- .../boot/spi/MetadataBuildingOptions.java | 4 +- .../AbstractDynamicMapInstantiator.java | 64 +++++++++ ...va => AbstractEntityInstantiatorPojo.java} | 19 +-- .../internal/AbstractPojoInstantiator.java | 8 +- .../internal/DynamicMapInstantiator.java | 131 ------------------ .../EmbeddableInstantiatorDynamicMap.java | 31 +++++ .../EmbeddableInstantiatorPojoOptimized.java | 37 +++++ .../EmbeddableInstantiatorPojoStandard.java | 70 ++++++++++ ... EmbeddableRepresentationStrategyMap.java} | 15 +- ...EmbeddableRepresentationStrategyPojo.java} | 26 ++-- .../EntityInstantiatorDynamicMap.java | 78 +++++++++++ ...a => EntityInstantiatorPojoOptimized.java} | 19 +-- .../EntityInstantiatorPojoStandard.java | 106 ++++++++++++++ ...a => EntityRepresentationStrategyMap.java} | 16 +-- ...tyRepresentationStrategyPojoStandard.java} | 42 +++--- ...edTypeRepresentationResolverStandard.java} | 12 +- .../OptimizedPojoInstantiatorImpl.java | 28 ---- .../internal/PojoInstantiatorImpl.java | 20 --- .../metamodel/spi/EmbeddableInstantiator.java | 23 +++ .../spi/EmbeddableRepresentationStrategy.java | 2 +- .../metamodel/spi/EntityInstantiator.java | 21 +++ .../spi/EntityRepresentationStrategy.java | 2 +- .../hibernate/metamodel/spi/Instantiator.java | 6 +- .../AbstractEmbeddableInitializer.java | 9 +- .../testing/boot/BootstrapContextImpl.java | 6 +- 26 files changed, 526 insertions(+), 274 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractDynamicMapInstantiator.java rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{PojoEntityInstantiatorImpl.java => AbstractEntityInstantiatorPojo.java} (81%) delete mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/DynamicMapInstantiator.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorDynamicMap.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoOptimized.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{StandardMapEmbeddableRepresentationStrategy.java => EmbeddableRepresentationStrategyMap.java} (78%) rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{StandardPojoEmbeddableRepresentationStrategy.java => EmbeddableRepresentationStrategyPojo.java} (88%) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorDynamicMap.java rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{OptimizedPojoEntityInstantiatorImpl.java => EntityInstantiatorPojoOptimized.java} (55%) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{StandardMapEntityRepresentationStrategy.java => EntityRepresentationStrategyMap.java} (87%) rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{StandardPojoEntityRepresentationStrategy.java => EntityRepresentationStrategyPojoStandard.java} (92%) rename hibernate-core/src/main/java/org/hibernate/metamodel/internal/{StandardManagedTypeRepresentationResolver.java => ManagedTypeRepresentationResolverStandard.java} (83%) delete mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoInstantiatorImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableInstantiator.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityInstantiator.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java index 098bfe8725c5..850d2db2ed24 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/BootstrapContextImpl.java @@ -15,7 +15,6 @@ import org.hibernate.AssertionFailure; import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.java.JavaReflectionManager; -import org.hibernate.boot.AttributeConverterInfo; import org.hibernate.boot.CacheRegionDefinition; import org.hibernate.boot.archive.scan.internal.StandardScanOptions; import org.hibernate.boot.archive.scan.spi.ScanEnvironment; @@ -35,7 +34,7 @@ import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.jpa.internal.MutableJpaComplianceImpl; import org.hibernate.jpa.spi.MutableJpaCompliance; -import org.hibernate.metamodel.internal.StandardManagedTypeRepresentationResolver; +import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard; import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.type.spi.TypeConfiguration; @@ -109,7 +108,7 @@ public BootstrapContextImpl( configService.getSettings().get( AvailableSettings.SCANNER_ARCHIVE_INTERPRETER ) ); - this.representationStrategySelector = StandardManagedTypeRepresentationResolver.INSTANCE; + this.representationStrategySelector = ManagedTypeRepresentationResolverStandard.INSTANCE; this.typeConfiguration = new TypeConfiguration(); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java index b10b5ee5678e..206c258de27e 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/MetadataBuildingOptions.java @@ -23,7 +23,7 @@ import org.hibernate.cfg.MetadataSourceType; import org.hibernate.collection.internal.StandardCollectionSemanticsResolver; import org.hibernate.collection.spi.CollectionSemanticsResolver; -import org.hibernate.metamodel.internal.StandardManagedTypeRepresentationResolver; +import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard; import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver; import org.jboss.jandex.IndexView; @@ -53,7 +53,7 @@ public interface MetadataBuildingOptions { default ManagedTypeRepresentationResolver getManagedTypeRepresentationResolver() { // for now always return the standard one - return StandardManagedTypeRepresentationResolver.INSTANCE; + return ManagedTypeRepresentationResolverStandard.INSTANCE; } default CollectionSemanticsResolver getPersistentCollectionRepresentationResolver() { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractDynamicMapInstantiator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractDynamicMapInstantiator.java new file mode 100644 index 000000000000..c6687155d2d1 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractDynamicMapInstantiator.java @@ -0,0 +1,64 @@ +/* + * 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 org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.metamodel.spi.Instantiator; + +/** + * Base support for dynamic-map instantiators + * + * @author Steve Ebersole + */ +public abstract class AbstractDynamicMapInstantiator implements Instantiator { + public static final String TYPE_KEY = "$type$"; + + private final String roleName; + + public AbstractDynamicMapInstantiator(String roleName) { + if ( roleName == null ) { + throw new IllegalArgumentException( "`roleName` passed to dynamic-map instantiator cannot be null" ); + } + this.roleName = roleName; + } + + public String getRoleName() { + return roleName; + } + + @Override + public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) { + if ( object instanceof Map ) { + //noinspection rawtypes + final String type = (String) ( (Map) object ).get( TYPE_KEY ); + return isSameRole( type ); + } + + // todo (6.0) : should this be an exception instead? + return false; + } + + protected boolean isSameRole(String type) { + return roleName.equals( type ); + } + + @Override + public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) { + return isInstance( object, sessionFactory ); + } + + @SuppressWarnings("rawtypes") + protected Map generateDataMap() { + final Map map = new HashMap(); + //noinspection unchecked + map.put( TYPE_KEY, roleName ); + return map; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoEntityInstantiatorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java similarity index 81% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoEntityInstantiatorImpl.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java index da84a7a3d368..a176f73f2cd0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoEntityInstantiatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractEntityInstantiatorPojo.java @@ -12,30 +12,32 @@ import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.PersistentClass; +import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** + * Base support for instantiating entity values as POJO representation + * * @author Steve Ebersole */ -public class PojoEntityInstantiatorImpl extends PojoInstantiatorImpl { - +public abstract class AbstractEntityInstantiatorPojo extends AbstractPojoInstantiator implements EntityInstantiator { private final EntityMetamodel entityMetamodel; - private final Class proxyInterface; + private final Class proxyInterface; private final boolean applyBytecodeInterception; - public PojoEntityInstantiatorImpl( + public AbstractEntityInstantiatorPojo( EntityMetamodel entityMetamodel, PersistentClass persistentClass, - JavaTypeDescriptor javaTypeDescriptor) { - super( javaTypeDescriptor ); - this.entityMetamodel = entityMetamodel; + JavaTypeDescriptor javaTypeDescriptor) { + super( javaTypeDescriptor.getJavaTypeClass() ); + this.entityMetamodel = entityMetamodel; this.proxyInterface = persistentClass.getProxyInterface(); + this.applyBytecodeInterception = PersistentAttributeInterceptable.class.isAssignableFrom( persistentClass.getMappedClass() ); } - @Override protected Object applyInterception(Object entity) { if ( !applyBytecodeInterception ) { return entity; @@ -59,5 +61,4 @@ public boolean isInstance(Object object, SessionFactoryImplementor sessionFactor //this one needed only for guessEntityMode() ( proxyInterface!=null && proxyInterface.isInstance(object) ); } - } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractPojoInstantiator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractPojoInstantiator.java index 2961435e3eca..f220a3fcef87 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractPojoInstantiator.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractPojoInstantiator.java @@ -11,18 +11,20 @@ import org.hibernate.metamodel.spi.Instantiator; /** + * Base support for POJO-based instantiation + * * @author Steve Ebersole */ public abstract class AbstractPojoInstantiator implements Instantiator { - private final Class mappedPojoClass; + private final Class mappedPojoClass; private final boolean isAbstract; - public AbstractPojoInstantiator(Class mappedPojoClass) { + public AbstractPojoInstantiator(Class mappedPojoClass) { this.mappedPojoClass = mappedPojoClass; this.isAbstract = ReflectHelper.isAbstractClass( mappedPojoClass ); } - public Class getMappedPojoClass() { + public Class getMappedPojoClass() { return mappedPojoClass; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/DynamicMapInstantiator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/DynamicMapInstantiator.java deleted file mode 100644 index 12cc6683b12e..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/DynamicMapInstantiator.java +++ /dev/null @@ -1,131 +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.metamodel.internal; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.hibernate.EntityNameResolver; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.mapping.Component; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.metamodel.spi.Instantiator; - -/** - * @author Steve Ebersole - */ -public class DynamicMapInstantiator implements Instantiator { - public static final EntityNameResolver ENTITY_NAME_RESOLVER = entity -> { - if ( ! (entity instanceof Map) ) { - return null; - } - final String entityName = extractEmbeddedEntityName( (Map) entity ); - if ( entityName == null ) { - throw new HibernateException( "Could not determine type of dynamic map entity" ); - } - return entityName; - }; - - public static final String KEY = "$type$"; - - private final String roleName; - private final Set isInstanceEntityNames = new HashSet<>(); - - public DynamicMapInstantiator(Component bootMapping) { - this.roleName = bootMapping.getRoleName(); - } - - public DynamicMapInstantiator(PersistentClass bootMapping) { - this.roleName = bootMapping.getEntityName(); - - isInstanceEntityNames.add( roleName ); - if ( bootMapping.hasSubclasses() ) { - Iterator itr = bootMapping.getSubclassClosureIterator(); - while ( itr.hasNext() ) { - final PersistentClass subclassInfo = ( PersistentClass ) itr.next(); - isInstanceEntityNames.add( subclassInfo.getEntityName() ); - } - } - } - - @Override - public Map instantiate(SessionFactoryImplementor sessionFactory) { - Map map = generateMap(); - if ( roleName != null ) { - //noinspection unchecked - map.put( KEY, roleName ); - } - return map; - } - - @SuppressWarnings("WeakerAccess") - protected Map generateMap() { - return new HashMap(); - } - - @Override - public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) { - if ( object instanceof Map ) { - if ( roleName == null ) { - return true; - } - final String type = (String) ( (Map) object ).get( KEY ); - return type == null || isInstanceEntityNames.contains( type ); - } - else { - return false; - } - } - - @Override - public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) { - return isInstance( object, sessionFactory ); - } - - - public static class BasicEntityNameResolver implements EntityNameResolver { - public static final BasicEntityNameResolver INSTANCE = new BasicEntityNameResolver(); - - @Override - public String resolveEntityName(Object entity) { - if ( ! (entity instanceof Map) ) { - return null; - } - final String entityName = extractEmbeddedEntityName( (Map) entity ); - if ( entityName == null ) { - throw new HibernateException( "Could not determine type of dynamic map entity" ); - } - return entityName; - } - - @Override - public boolean equals(Object obj) { - return obj != null && getClass().equals( obj.getClass() ); - } - - @Override - public int hashCode() { - return getClass().hashCode(); - } - } - - public static String extractEmbeddedEntityName(Map entity) { - if ( entity == null ) { - return null; - } - final String entityName = (String) entity.get( KEY ); - if ( entityName == null ) { - throw new HibernateException( "Could not determine type of dynamic map entity" ); - } - return entityName; - } - -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorDynamicMap.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorDynamicMap.java new file mode 100644 index 000000000000..d20ab5e96400 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorDynamicMap.java @@ -0,0 +1,31 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.metamodel.internal; + +import java.util.function.Supplier; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.mapping.Component; +import org.hibernate.metamodel.spi.EmbeddableInstantiator; + +/** + * Support for instantiating embeddables as dynamic-map representation + * + * @author Steve Ebersole + */ +public class EmbeddableInstantiatorDynamicMap + extends AbstractDynamicMapInstantiator + implements EmbeddableInstantiator { + public EmbeddableInstantiatorDynamicMap(Component bootDescriptor) { + super( bootDescriptor.getRoleName() ); + } + + @Override + public Object instantiate(Supplier valuesAccess, SessionFactoryImplementor sessionFactory) { + return generateDataMap(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoOptimized.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoOptimized.java new file mode 100644 index 000000000000..b7444a9cf5fc --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoOptimized.java @@ -0,0 +1,37 @@ +/* + * 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.function.Supplier; + +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.metamodel.spi.EmbeddableInstantiator; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; + +import static org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimizer; + +/** + * Support for instantiating embeddables as POJO representation + * using bytecode optimizer + * + * @author Steve Ebersole + */ +public class EmbeddableInstantiatorPojoOptimized extends AbstractPojoInstantiator implements EmbeddableInstantiator { + private final InstantiationOptimizer instantiationOptimizer; + + public EmbeddableInstantiatorPojoOptimized( + JavaTypeDescriptor javaTypeDescriptor, + InstantiationOptimizer instantiationOptimizer) { + super( javaTypeDescriptor.getJavaTypeClass() ); + this.instantiationOptimizer = instantiationOptimizer; + } + + @Override + public Object instantiate(Supplier valuesAccess, SessionFactoryImplementor sessionFactory) { + return instantiationOptimizer.newInstance(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java new file mode 100644 index 000000000000..cc7d4faa3cd5 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java @@ -0,0 +1,70 @@ +/* + * 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.lang.reflect.Constructor; +import java.util.function.Supplier; + +import org.hibernate.InstantiationException; +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.spi.EmbeddableInstantiator; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; + +/** + * Support for instantiating embeddables as POJO representation + * + * @author Steve Ebersole + */ +public class EmbeddableInstantiatorPojoStandard extends AbstractPojoInstantiator implements EmbeddableInstantiator { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PojoInstantiatorImpl.class ); + + private final Constructor constructor; + + public EmbeddableInstantiatorPojoStandard( + @SuppressWarnings("unused") Component bootDescriptor, + JavaTypeDescriptor javaTypeDescriptor) { + super( javaTypeDescriptor.getJavaTypeClass() ); + + constructor = resolveConstructor( javaTypeDescriptor.getJavaTypeClass() ); + + // todo (6.0) : add support for constructor value injection + } + + protected static Constructor resolveConstructor(Class mappedPojoClass) { + try { + return ReflectHelper.getDefaultConstructor( mappedPojoClass); + } + catch ( PropertyNotFoundException e ) { + LOG.noDefaultConstructor( mappedPojoClass.getName() ); + } + + return null; + } + + @Override + public Object instantiate(Supplier valuesAccess, SessionFactoryImplementor sessionFactory) { + if ( isAbstract() ) { + throw new InstantiationException( "Cannot instantiate abstract class or interface: ", getMappedPojoClass() ); + } + else if ( constructor == null ) { + throw new InstantiationException( "No default constructor for embeddable: ", getMappedPojoClass() ); + } + else { + try { + return constructor.newInstance( (Object[]) null ); + } + catch ( Exception e ) { + throw new InstantiationException( "Could not instantiate entity: ", getMappedPojoClass(), e ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardMapEmbeddableRepresentationStrategy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableRepresentationStrategyMap.java similarity index 78% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardMapEmbeddableRepresentationStrategy.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableRepresentationStrategyMap.java index a5e3abce2fd9..85663fd88d72 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardMapEmbeddableRepresentationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableRepresentationStrategyMap.java @@ -12,8 +12,8 @@ import org.hibernate.mapping.Component; import org.hibernate.mapping.Property; import org.hibernate.metamodel.RepresentationMode; +import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.metamodel.spi.EmbeddableRepresentationStrategy; -import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl; import org.hibernate.property.access.spi.PropertyAccess; @@ -22,15 +22,15 @@ /** * @author Steve Ebersole */ -public class StandardMapEmbeddableRepresentationStrategy implements EmbeddableRepresentationStrategy { +public class EmbeddableRepresentationStrategyMap implements EmbeddableRepresentationStrategy { private final JavaTypeDescriptor mapJtd; - private final DynamicMapInstantiator instantiator; + private final EmbeddableInstantiator instantiator; - public StandardMapEmbeddableRepresentationStrategy( + public EmbeddableRepresentationStrategyMap( Component bootDescriptor, RuntimeModelCreationContext creationContext) { this.mapJtd = creationContext.getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class ); - this.instantiator = new DynamicMapInstantiator( bootDescriptor ); + this.instantiator = new EmbeddableInstantiatorDynamicMap( bootDescriptor ); } @Override @@ -57,8 +57,7 @@ public PropertyAccess resolvePropertyAccess(Property bootAttributeDescriptor) { } @Override - public Instantiator getInstantiator() { - //noinspection unchecked - return (Instantiator) instantiator; + public EmbeddableInstantiator getInstantiator() { + return instantiator; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardPojoEmbeddableRepresentationStrategy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableRepresentationStrategyPojo.java similarity index 88% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardPojoEmbeddableRepresentationStrategy.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableRepresentationStrategyPojo.java index dcecc0e54ae8..fba0754b1c78 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardPojoEmbeddableRepresentationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableRepresentationStrategyPojo.java @@ -20,7 +20,7 @@ import org.hibernate.mapping.IndexBackref; import org.hibernate.mapping.Property; import org.hibernate.metamodel.RepresentationMode; -import org.hibernate.metamodel.spi.Instantiator; +import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl; import org.hibernate.property.access.internal.PropertyAccessStrategyIndexBackRefImpl; @@ -31,16 +31,15 @@ /** * @author Steve Ebersole */ -public class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbeddableRepresentationStrategy { +public class EmbeddableRepresentationStrategyPojo extends AbstractEmbeddableRepresentationStrategy { private final StrategySelector strategySelector; private final ReflectionOptimizer reflectionOptimizer; - private final Instantiator instantiator; + private final EmbeddableInstantiator instantiator; - public StandardPojoEmbeddableRepresentationStrategy( + public EmbeddableRepresentationStrategyPojo( Component bootDescriptor, RuntimeModelCreationContext creationContext) { - //noinspection unchecked super( bootDescriptor, creationContext.getTypeConfiguration() @@ -67,12 +66,16 @@ public StandardPojoEmbeddableRepresentationStrategy( if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) { final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer(); - this.instantiator = instantiationOptimizer != null - ? new OptimizedPojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor(), instantiationOptimizer ) - : new PojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor() ); + this.instantiator = new EmbeddableInstantiatorPojoOptimized( + getEmbeddableJavaTypeDescriptor(), + instantiationOptimizer + ); } else { - this.instantiator = new PojoInstantiatorImpl<>( getEmbeddableJavaTypeDescriptor() ); + this.instantiator = new EmbeddableInstantiatorPojoStandard( + bootDescriptor, + getEmbeddableJavaTypeDescriptor() + ); } } @@ -146,7 +149,7 @@ private ReflectionOptimizer buildReflectionOptimizer( final String[] getterNames = new String[getPropertySpan()]; final String[] setterNames = new String[getPropertySpan()]; - final Class[] propTypes = new Class[getPropertySpan()]; + final Class[] propTypes = new Class[getPropertySpan()]; for ( int i = 0; i < getPropertyAccesses().length; i++ ) { final PropertyAccess propertyAccess = getPropertyAccesses()[i]; @@ -170,8 +173,7 @@ public RepresentationMode getMode() { } @Override - public Instantiator getInstantiator() { - //noinspection unchecked + public EmbeddableInstantiator getInstantiator() { return instantiator; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorDynamicMap.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorDynamicMap.java new file mode 100644 index 000000000000..ac312c02c58d --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorDynamicMap.java @@ -0,0 +1,78 @@ +/* + * 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.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.hibernate.EntityNameResolver; +import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.metamodel.spi.EntityInstantiator; + +/** + * Support for instantiating entity values as dynamic-map representation + * + * @author Steve Ebersole + */ +public class EntityInstantiatorDynamicMap + extends AbstractDynamicMapInstantiator + implements EntityInstantiator { + private final Set entityRoleNames = new HashSet<>(); + + public EntityInstantiatorDynamicMap(PersistentClass bootDescriptor) { + super( bootDescriptor.getEntityName() ); + + entityRoleNames.add( getRoleName() ); + if ( bootDescriptor.hasSubclasses() ) { + final Iterator itr = bootDescriptor.getSubclassClosureIterator(); + while ( itr.hasNext() ) { + final PersistentClass subclassInfo = itr.next(); + entityRoleNames.add( subclassInfo.getEntityName() ); + } + } + } + + @Override + public Object instantiate(SessionFactoryImplementor sessionFactory) { + return generateDataMap(); + } + + @Override + protected boolean isSameRole(String type) { + return super.isSameRole( type ) || isPartOfHierarchy( type ); + } + + private boolean isPartOfHierarchy(String type) { + return entityRoleNames.contains( type ); + } + + public static final EntityNameResolver ENTITY_NAME_RESOLVER = entity -> { + if ( ! (entity instanceof Map ) ) { + return null; + } + final String entityName = extractEmbeddedEntityName( (Map) entity ); + if ( entityName == null ) { + throw new HibernateException( "Could not determine type of dynamic map entity" ); + } + return entityName; + }; + + public static String extractEmbeddedEntityName(Map entity) { + if ( entity == null ) { + return null; + } + final String entityName = (String) entity.get( TYPE_KEY ); + if ( entityName == null ) { + throw new HibernateException( "Could not determine type of dynamic map entity" ); + } + return entityName; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoEntityInstantiatorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java similarity index 55% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoEntityInstantiatorImpl.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java index 568cf3507920..a7551970ba3a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoEntityInstantiatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoOptimized.java @@ -6,29 +6,32 @@ */ package org.hibernate.metamodel.internal; -import org.hibernate.bytecode.spi.ReflectionOptimizer; +import org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimizer; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.PersistentClass; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; /** + * Support for instantiating entity values as POJO representation using + * bytecode optimizer + * * @author Steve Ebersole */ -public class OptimizedPojoEntityInstantiatorImpl extends PojoEntityInstantiatorImpl { - private final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer; +public class EntityInstantiatorPojoOptimized extends AbstractEntityInstantiatorPojo { + private final InstantiationOptimizer instantiationOptimizer; - public OptimizedPojoEntityInstantiatorImpl( + public EntityInstantiatorPojoOptimized( EntityMetamodel entityMetamodel, PersistentClass persistentClass, - JavaTypeDescriptor javaTypeDescriptor, - ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer) { + JavaTypeDescriptor javaTypeDescriptor, + InstantiationOptimizer instantiationOptimizer) { super( entityMetamodel, persistentClass, javaTypeDescriptor ); this.instantiationOptimizer = instantiationOptimizer; } @Override - public J instantiate(SessionFactoryImplementor sessionFactory) { - return (J) applyInterception( instantiationOptimizer.newInstance() ); + public Object instantiate(SessionFactoryImplementor sessionFactory) { + return applyInterception( instantiationOptimizer.newInstance() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java new file mode 100644 index 000000000000..7f649de2f371 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityInstantiatorPojoStandard.java @@ -0,0 +1,106 @@ +/* + * 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.lang.reflect.Constructor; + +import org.hibernate.InstantiationException; +import org.hibernate.PropertyNotFoundException; +import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor; +import org.hibernate.engine.spi.PersistentAttributeInterceptable; +import org.hibernate.engine.spi.PersistentAttributeInterceptor; +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.PersistentClass; +import org.hibernate.tuple.entity.EntityMetamodel; +import org.hibernate.type.descriptor.java.JavaTypeDescriptor; + +/** + * Support for instantiating entity values as POJO representation + */ +public class EntityInstantiatorPojoStandard extends AbstractEntityInstantiatorPojo { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EntityInstantiatorPojoStandard.class ); + + private final EntityMetamodel entityMetamodel; + private final Class proxyInterface; + private final boolean applyBytecodeInterception; + + private final Constructor constructor; + + public EntityInstantiatorPojoStandard( + EntityMetamodel entityMetamodel, + PersistentClass persistentClass, + JavaTypeDescriptor javaTypeDescriptor) { + super( entityMetamodel, persistentClass, javaTypeDescriptor ); + + this.entityMetamodel = entityMetamodel; + this.proxyInterface = persistentClass.getProxyInterface(); + + this.constructor = isAbstract() + ? null + : resolveConstructor( getMappedPojoClass() ); + + this.applyBytecodeInterception = PersistentAttributeInterceptable.class.isAssignableFrom( persistentClass.getMappedClass() ); + } + + protected static Constructor resolveConstructor(Class mappedPojoClass) { + try { + return ReflectHelper.getDefaultConstructor( mappedPojoClass); + } + catch ( PropertyNotFoundException e ) { + LOG.noDefaultConstructor( mappedPojoClass.getName() ); + } + + return null; + } + + @Override + protected Object applyInterception(Object entity) { + if ( !applyBytecodeInterception ) { + return entity; + } + + PersistentAttributeInterceptor interceptor = new LazyAttributeLoadingInterceptor( + entityMetamodel.getName(), + null, + entityMetamodel.getBytecodeEnhancementMetadata() + .getLazyAttributesMetadata() + .getLazyAttributeNames(), + null + ); + ( (PersistentAttributeInterceptable) entity ).$$_hibernate_setInterceptor( interceptor ); + return entity; + } + + @Override + public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) { + return super.isInstance( object, sessionFactory ) || + //this one needed only for guessEntityMode() + ( proxyInterface!=null && proxyInterface.isInstance(object) ); + } + + @Override + public Object instantiate(SessionFactoryImplementor sessionFactory) { + if ( isAbstract() ) { + throw new InstantiationException( "Cannot instantiate abstract class or interface: ", getMappedPojoClass() ); + } + else if ( constructor == null ) { + throw new InstantiationException( "No default constructor for entity: ", getMappedPojoClass() ); + } + else { + try { + return applyInterception( constructor.newInstance( (Object[]) null ) ); + } + catch ( Exception e ) { + throw new InstantiationException( "Could not instantiate entity: ", getMappedPojoClass(), e ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardMapEntityRepresentationStrategy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyMap.java similarity index 87% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardMapEntityRepresentationStrategy.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyMap.java index b338af9dd2be..290f58663905 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardMapEntityRepresentationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyMap.java @@ -19,8 +19,8 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.metamodel.RepresentationMode; +import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.metamodel.spi.EntityRepresentationStrategy; -import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.property.access.internal.PropertyAccessStrategyMapImpl; import org.hibernate.property.access.spi.PropertyAccess; @@ -31,17 +31,17 @@ /** * @author Steve Ebersole */ -public class StandardMapEntityRepresentationStrategy implements EntityRepresentationStrategy { - private static final CoreMessageLogger LOG = CoreLogging.messageLogger( StandardMapEntityRepresentationStrategy.class ); +public class EntityRepresentationStrategyMap implements EntityRepresentationStrategy { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EntityRepresentationStrategyMap.class ); private final JavaTypeDescriptor mapJtd; private final ProxyFactory proxyFactory; - private final DynamicMapInstantiator instantiator; + private final EntityInstantiatorDynamicMap instantiator; private final Map propertyAccessMap = new ConcurrentHashMap<>(); - public StandardMapEntityRepresentationStrategy( + public EntityRepresentationStrategyMap( PersistentClass bootType, RuntimeModelCreationContext creationContext) { this.mapJtd = creationContext.getTypeConfiguration() @@ -49,7 +49,7 @@ public StandardMapEntityRepresentationStrategy( .getDescriptor( Map.class ); this.proxyFactory = createProxyFactory( bootType ); - this.instantiator = new DynamicMapInstantiator( bootType ); + this.instantiator = new EntityInstantiatorDynamicMap( bootType ); //noinspection unchecked final Iterator itr = bootType.getPropertyClosureIterator(); @@ -110,7 +110,7 @@ public PropertyAccess resolvePropertyAccess(Property bootAttributeDescriptor) { } @Override - public Instantiator getInstantiator() { + public EntityInstantiator getInstantiator() { return instantiator; } @@ -131,6 +131,6 @@ public JavaTypeDescriptor getProxyJavaTypeDescriptor() { @Override public void visitEntityNameResolvers(Consumer consumer) { - consumer.accept( DynamicMapInstantiator.ENTITY_NAME_RESOLVER ); + consumer.accept( EntityInstantiatorDynamicMap.ENTITY_NAME_RESOLVER ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardPojoEntityRepresentationStrategy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java similarity index 92% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardPojoEntityRepresentationStrategy.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java index b26cabaa6cf6..b21902a62834 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardPojoEntityRepresentationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java @@ -20,6 +20,7 @@ import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.bytecode.spi.BytecodeProvider; import org.hibernate.bytecode.spi.ReflectionOptimizer; +import org.hibernate.bytecode.spi.ReflectionOptimizer.InstantiationOptimizer; import org.hibernate.cfg.Environment; import org.hibernate.classic.Lifecycle; import org.hibernate.engine.spi.PersistentAttributeInterceptable; @@ -36,8 +37,8 @@ import org.hibernate.mapping.Property; import org.hibernate.mapping.Subclass; import org.hibernate.metamodel.RepresentationMode; +import org.hibernate.metamodel.spi.EntityInstantiator; import org.hibernate.metamodel.spi.EntityRepresentationStrategy; -import org.hibernate.metamodel.spi.Instantiator; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.property.access.internal.PropertyAccessBasicImpl; @@ -58,8 +59,8 @@ /** * @author Steve Ebersole */ -public class StandardPojoEntityRepresentationStrategy implements EntityRepresentationStrategy { - private static final CoreMessageLogger LOG = CoreLogging.messageLogger( StandardPojoEntityRepresentationStrategy.class ); +public class EntityRepresentationStrategyPojoStandard implements EntityRepresentationStrategy { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( EntityRepresentationStrategyPojoStandard.class ); private final JavaTypeDescriptor mappedJtd; private final JavaTypeDescriptor proxyJtd; @@ -69,16 +70,16 @@ public class StandardPojoEntityRepresentationStrategy implements EntityRepresent private final ReflectionOptimizer reflectionOptimizer; private final ProxyFactory proxyFactory; - private final Instantiator instantiator; + private final EntityInstantiator instantiator; private final StrategySelector strategySelector; private final String identifierPropertyName; private final PropertyAccess identifierPropertyAccess; private final Map propertyAccessMap = new ConcurrentHashMap<>(); - private final StandardPojoEmbeddableRepresentationStrategy mapsIdRepresentationStrategy; + private final EmbeddableRepresentationStrategyPojo mapsIdRepresentationStrategy; - public StandardPojoEntityRepresentationStrategy( + public EntityRepresentationStrategyPojoStandard( PersistentClass bootDescriptor, EntityPersister runtimeDescriptor, RuntimeModelCreationContext creationContext) { @@ -110,13 +111,13 @@ public StandardPojoEntityRepresentationStrategy( if ( bootDescriptorIdentifier instanceof Component ) { if ( bootDescriptor.getIdentifierMapper() != null ) { - mapsIdRepresentationStrategy = new StandardPojoEmbeddableRepresentationStrategy( + mapsIdRepresentationStrategy = new EmbeddableRepresentationStrategyPojo( bootDescriptor.getIdentifierMapper(), creationContext ); } else if ( bootDescriptorIdentifier != null ) { - mapsIdRepresentationStrategy = new StandardPojoEmbeddableRepresentationStrategy( + mapsIdRepresentationStrategy = new EmbeddableRepresentationStrategyPojo( (Component) bootDescriptorIdentifier, creationContext ); @@ -153,22 +154,17 @@ else if ( bootDescriptorIdentifier != null ) { this.reflectionOptimizer = resolveReflectionOptimizer( bootDescriptor, bytecodeProvider, sessionFactory ); - if ( reflectionOptimizer != null ) { - final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer(); - if ( instantiationOptimizer != null ) { - this.instantiator = new OptimizedPojoEntityInstantiatorImpl<>( - entityMetamodel, - bootDescriptor, - mappedJtd, - instantiationOptimizer - ); - } - else { - this.instantiator = new PojoEntityInstantiatorImpl<>( entityMetamodel, bootDescriptor, mappedJtd ); - } + if ( reflectionOptimizer != null && reflectionOptimizer.getInstantiationOptimizer() != null ) { + final InstantiationOptimizer instantiationOptimizer = reflectionOptimizer.getInstantiationOptimizer(); + this.instantiator = new EntityInstantiatorPojoOptimized( + entityMetamodel, + bootDescriptor, + mappedJtd, + instantiationOptimizer + ); } else { - this.instantiator = new PojoEntityInstantiatorImpl<>( entityMetamodel, bootDescriptor, mappedJtd ); + this.instantiator = new EntityInstantiatorPojoStandard( entityMetamodel, bootDescriptor, mappedJtd ); } } @@ -378,7 +374,7 @@ public ReflectionOptimizer getReflectionOptimizer() { } @Override - public Instantiator getInstantiator() { + public EntityInstantiator getInstantiator() { return instantiator; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardManagedTypeRepresentationResolver.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManagedTypeRepresentationResolverStandard.java similarity index 83% rename from hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardManagedTypeRepresentationResolver.java rename to hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManagedTypeRepresentationResolverStandard.java index e382f9bc8c62..cb75415df1cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/StandardManagedTypeRepresentationResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManagedTypeRepresentationResolverStandard.java @@ -19,11 +19,11 @@ /** * @author Steve Ebersole */ -public class StandardManagedTypeRepresentationResolver implements ManagedTypeRepresentationResolver { +public class ManagedTypeRepresentationResolverStandard implements ManagedTypeRepresentationResolver { /** * Singleton access */ - public static final StandardManagedTypeRepresentationResolver INSTANCE = new StandardManagedTypeRepresentationResolver(); + public static final ManagedTypeRepresentationResolverStandard INSTANCE = new ManagedTypeRepresentationResolverStandard(); @Override public EntityRepresentationStrategy resolveStrategy( @@ -42,7 +42,7 @@ public EntityRepresentationStrategy resolveStrategy( } if ( representation == RepresentationMode.MAP ) { - return new StandardMapEntityRepresentationStrategy( bootDescriptor, creationContext ); + return new EntityRepresentationStrategyMap( bootDescriptor, creationContext ); } else { // todo (6.0) : fix this @@ -51,7 +51,7 @@ public EntityRepresentationStrategy resolveStrategy( // // instead, resolve ReflectionOptimizer once - here - and pass along to // StandardPojoRepresentationStrategy - return new StandardPojoEntityRepresentationStrategy( bootDescriptor, runtimeDescriptor, creationContext ); + return new EntityRepresentationStrategyPojoStandard( bootDescriptor, runtimeDescriptor, creationContext ); } } @@ -71,7 +71,7 @@ public EmbeddableRepresentationStrategy resolveStrategy( } if ( representation == RepresentationMode.MAP ) { - return new StandardMapEmbeddableRepresentationStrategy( bootDescriptor, creationContext ); + return new EmbeddableRepresentationStrategyMap( bootDescriptor, creationContext ); } else { // todo (6.0) : fix this @@ -80,7 +80,7 @@ public EmbeddableRepresentationStrategy resolveStrategy( // // instead, resolve ReflectionOptimizer once - here - and pass along to // StandardPojoRepresentationStrategy - return new StandardPojoEmbeddableRepresentationStrategy( bootDescriptor, creationContext ); + return new EmbeddableRepresentationStrategyPojo( bootDescriptor, creationContext ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoInstantiatorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoInstantiatorImpl.java deleted file mode 100644 index dbe959782836..000000000000 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/OptimizedPojoInstantiatorImpl.java +++ /dev/null @@ -1,28 +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.metamodel.internal; - -import org.hibernate.bytecode.spi.ReflectionOptimizer; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.type.descriptor.java.JavaTypeDescriptor; - -/** - * @author Steve Ebersole - */ -public class OptimizedPojoInstantiatorImpl extends AbstractPojoInstantiator { - private final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer; - - public OptimizedPojoInstantiatorImpl(JavaTypeDescriptor javaTypeDescriptor, ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer) { - super( javaTypeDescriptor.getJavaTypeClass() ); - this.instantiationOptimizer = instantiationOptimizer; - } - - @Override - public Object instantiate(SessionFactoryImplementor sessionFactory) { - return instantiationOptimizer.newInstance(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoInstantiatorImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoInstantiatorImpl.java index 05da10df8467..12784f6f9bfa 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoInstantiatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PojoInstantiatorImpl.java @@ -45,26 +45,6 @@ protected static Constructor resolveConstructor(Class mappedPojoClass) { return null; } - - @Override - @SuppressWarnings("unchecked") - public J instantiate(SessionFactoryImplementor sessionFactory) { - if ( isAbstract() ) { - throw new InstantiationException( "Cannot instantiate abstract class or interface: ", getMappedPojoClass() ); - } - else if ( constructor == null ) { - throw new InstantiationException( "No default constructor for entity: ", getMappedPojoClass() ); - } - else { - try { - return (J) applyInterception( constructor.newInstance( (Object[]) null ) ); - } - catch ( Exception e ) { - throw new InstantiationException( "Could not instantiate entity: ", getMappedPojoClass(), e ); - } - } - } - protected Object applyInterception(Object entity) { return entity; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableInstantiator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableInstantiator.java new file mode 100644 index 000000000000..6c856dada621 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableInstantiator.java @@ -0,0 +1,23 @@ +/* + * 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.spi; + +import java.util.function.Supplier; + +import org.hibernate.engine.spi.SessionFactoryImplementor; + +/** + * Contract for instantiating embeddable values + * + * @author Steve Ebersole + */ +public interface EmbeddableInstantiator extends Instantiator { + /** + * Create an instance of the embeddable + */ + Object instantiate(Supplier valuesAccess, SessionFactoryImplementor sessionFactory); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableRepresentationStrategy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableRepresentationStrategy.java index 27aed39c188c..55d047e7ac8b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableRepresentationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EmbeddableRepresentationStrategy.java @@ -13,5 +13,5 @@ public interface EmbeddableRepresentationStrategy extends ManagedTypeRepresentat /** * Create a delegate capable of instantiating instances of the represented type. */ - Instantiator getInstantiator(); + EmbeddableInstantiator getInstantiator(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityInstantiator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityInstantiator.java new file mode 100644 index 000000000000..642746ed0146 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityInstantiator.java @@ -0,0 +1,21 @@ +/* + * 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.spi; + +import org.hibernate.engine.spi.SessionFactoryImplementor; + +/** + * Contract for instantiating entity values + * + * @author Steve Ebersole + */ +public interface EntityInstantiator extends Instantiator { + /** + * Create an instance of managed entity + */ + Object instantiate(SessionFactoryImplementor sessionFactory); +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityRepresentationStrategy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityRepresentationStrategy.java index 81f3eea3b3c1..17d3d803db3e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityRepresentationStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/EntityRepresentationStrategy.java @@ -22,7 +22,7 @@ public interface EntityRepresentationStrategy extends ManagedTypeRepresentationS /** * Create a delegate capable of instantiating instances of the represented type. */ - Instantiator getInstantiator(); + EntityInstantiator getInstantiator(); /** * Create the delegate capable of producing proxies for the given entity diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/Instantiator.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/Instantiator.java index fe808723e2d0..75090717cd60 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/Instantiator.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/Instantiator.java @@ -15,11 +15,7 @@ * @author Steve Ebersole */ @Incubating -public interface Instantiator { - /** - * Create an instance of the managed embedded value structure. - */ - J instantiate(SessionFactoryImplementor sessionFactory); +public interface Instantiator { /** * Performs and "instance of" check to see if the given object is an diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/AbstractEmbeddableInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/AbstractEmbeddableInitializer.java index 4d2c927d4e0f..a90ce8e21193 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/AbstractEmbeddableInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/embeddable/AbstractEmbeddableInitializer.java @@ -8,6 +8,7 @@ import java.util.IdentityHashMap; import java.util.Map; +import java.util.function.Supplier; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.metamodel.mapping.EmbeddableMappingType; @@ -146,7 +147,7 @@ public void resolveInstance(RowProcessingState rowProcessingState) { compositeInstance = embeddableTypeDescriptor .getRepresentationStrategy() .getInstantiator() - .instantiate( rowProcessingState.getSession().getFactory() ); + .instantiate( VALUE_ACCESS, rowProcessingState.getSession().getFactory() ); } EmbeddableLoadingLogger.INSTANCE.debugf( @@ -155,6 +156,10 @@ public void resolveInstance(RowProcessingState rowProcessingState) { ); } + private static Supplier VALUE_ACCESS = () -> { + throw new NotYetImplementedFor6Exception( "Constructor value injection for embeddables not yet implemented" ); + }; + @Override public void initializeInstance(RowProcessingState rowProcessingState) { @@ -211,7 +216,7 @@ else if ( initializer instanceof EntityInitializer ) { Object target = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor() .getRepresentationStrategy() .getInstantiator() - .instantiate( rowProcessingState.getSession().getFactory() ); + .instantiate( VALUE_ACCESS, rowProcessingState.getSession().getFactory() ); embeddedModelPartDescriptor.getEmbeddableTypeDescriptor().setPropertyValues( target, resolvedValues diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/boot/BootstrapContextImpl.java b/hibernate-testing/src/main/java/org/hibernate/testing/boot/BootstrapContextImpl.java index 9e85f26da406..940c83cccf93 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/boot/BootstrapContextImpl.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/boot/BootstrapContextImpl.java @@ -9,8 +9,6 @@ import java.util.Collection; import java.util.Map; -import javax.xml.bind.JAXBContext; - import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.boot.CacheRegionDefinition; import org.hibernate.boot.archive.scan.spi.ScanEnvironment; @@ -26,7 +24,7 @@ import org.hibernate.boot.spi.ClassLoaderAccess; import org.hibernate.boot.spi.MetadataBuildingOptions; import org.hibernate.jpa.spi.MutableJpaCompliance; -import org.hibernate.metamodel.internal.StandardManagedTypeRepresentationResolver; +import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandard; import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.type.spi.TypeConfiguration; @@ -145,7 +143,7 @@ public Collection getCacheRegionDefinitions() { @Override public ManagedTypeRepresentationResolver getRepresentationStrategySelector() { - return StandardManagedTypeRepresentationResolver.INSTANCE; + return ManagedTypeRepresentationResolverStandard.INSTANCE; } @Override