Work on Instantiator in preparation for composite-user-type work

This commit is contained in:
Steve Ebersole 2021-06-24 10:29:47 -05:00
parent 69dc854d88
commit a6dc84e1fe
26 changed files with 526 additions and 274 deletions

View File

@ -15,7 +15,6 @@ import java.util.Map;
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.cfg.annotations.reflection.internal.JPAXMLOverriddenMetadat
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 class BootstrapContextImpl implements BootstrapContext {
configService.getSettings().get( AvailableSettings.SCANNER_ARCHIVE_INTERPRETER )
);
this.representationStrategySelector = StandardManagedTypeRepresentationResolver.INSTANCE;
this.representationStrategySelector = ManagedTypeRepresentationResolverStandard.INSTANCE;
this.typeConfiguration = new TypeConfiguration();
}

View File

@ -23,7 +23,7 @@ import org.hibernate.cache.spi.access.AccessType;
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() {

View File

@ -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;
}
}

View File

@ -12,30 +12,32 @@ import org.hibernate.engine.spi.PersistentAttributeInterceptable;
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<J> extends PojoInstantiatorImpl<J> {
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 class PojoEntityInstantiatorImpl<J> extends PojoInstantiatorImpl<J> {
//this one needed only for guessEntityMode()
( proxyInterface!=null && proxyInterface.isInstance(object) );
}
}

View File

@ -11,18 +11,20 @@ import org.hibernate.internal.util.ReflectHelper;
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;
}

View File

@ -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<Map> {
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<String> 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;
}
}

View File

@ -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<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
return generateDataMap();
}
}

View File

@ -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<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory) {
return instantiationOptimizer.newInstance();
}
}

View File

@ -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<Object[]> 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 );
}
}
}
}

View File

@ -12,8 +12,8 @@ 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.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 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @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 class StandardMapEmbeddableRepresentationStrategy implements EmbeddableRe
}
@Override
public <J> Instantiator<J> getInstantiator() {
//noinspection unchecked
return (Instantiator) instantiator;
public EmbeddableInstantiator getInstantiator() {
return instantiator;
}
}

View File

@ -20,7 +20,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.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 @@ import org.hibernate.property.access.spi.PropertyAccessStrategy;
/**
* @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 class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbedd
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 @@ public class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbedd
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 class StandardPojoEmbeddableRepresentationStrategy extends AbstractEmbedd
}
@Override
public <J> Instantiator<J> getInstantiator() {
//noinspection unchecked
public EmbeddableInstantiator getInstantiator() {
return instantiator;
}
}

View File

@ -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<String> entityRoleNames = new HashSet<>();
public EntityInstantiatorDynamicMap(PersistentClass bootDescriptor) {
super( bootDescriptor.getEntityName() );
entityRoleNames.add( getRoleName() );
if ( bootDescriptor.hasSubclasses() ) {
final Iterator<PersistentClass> 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;
}
}

View File

@ -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<J> extends PojoEntityInstantiatorImpl<J> {
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() );
}
}

View File

@ -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 );
}
}
}
}

View File

@ -19,8 +19,8 @@ import org.hibernate.internal.CoreMessageLogger;
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 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
/**
* @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<Map> mapJtd;
private final ProxyFactory proxyFactory;
private final DynamicMapInstantiator instantiator;
private final EntityInstantiatorDynamicMap instantiator;
private final Map<String, PropertyAccess> propertyAccessMap = new ConcurrentHashMap<>();
public StandardMapEntityRepresentationStrategy(
public EntityRepresentationStrategyMap(
PersistentClass bootType,
RuntimeModelCreationContext creationContext) {
this.mapJtd = creationContext.getTypeConfiguration()
@ -49,7 +49,7 @@ public class StandardMapEntityRepresentationStrategy implements EntityRepresenta
.getDescriptor( Map.class );
this.proxyFactory = createProxyFactory( bootType );
this.instantiator = new DynamicMapInstantiator( bootType );
this.instantiator = new EntityInstantiatorDynamicMap( bootType );
//noinspection unchecked
final Iterator<Property> itr = bootType.getPropertyClosureIterator();
@ -110,7 +110,7 @@ public class StandardMapEntityRepresentationStrategy implements EntityRepresenta
}
@Override
public Instantiator getInstantiator() {
public EntityInstantiator getInstantiator() {
return instantiator;
}
@ -131,6 +131,6 @@ public class StandardMapEntityRepresentationStrategy implements EntityRepresenta
@Override
public void visitEntityNameResolvers(Consumer<EntityNameResolver> consumer) {
consumer.accept( DynamicMapInstantiator.ENTITY_NAME_RESOLVER );
consumer.accept( EntityInstantiatorDynamicMap.ENTITY_NAME_RESOLVER );
}
}

View File

@ -20,6 +20,7 @@ import org.hibernate.MappingException;
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.PersistentClass;
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 @@ import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
/**
* @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<String, PropertyAccess> 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 class StandardPojoEntityRepresentationStrategy implements EntityRepresent
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 @@ public class StandardPojoEntityRepresentationStrategy implements EntityRepresent
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 class StandardPojoEntityRepresentationStrategy implements EntityRepresent
}
@Override
public Instantiator getInstantiator() {
public EntityInstantiator getInstantiator() {
return instantiator;
}

View File

@ -19,11 +19,11 @@ import org.hibernate.persister.entity.EntityPersister;
/**
* @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 class StandardManagedTypeRepresentationResolver implements ManagedTypeRep
}
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 class StandardManagedTypeRepresentationResolver implements ManagedTypeRep
//
// 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 class StandardManagedTypeRepresentationResolver implements ManagedTypeRep
}
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 class StandardManagedTypeRepresentationResolver implements ManagedTypeRep
//
// instead, resolve ReflectionOptimizer once - here - and pass along to
// StandardPojoRepresentationStrategy
return new StandardPojoEmbeddableRepresentationStrategy( bootDescriptor, creationContext );
return new EmbeddableRepresentationStrategyPojo( bootDescriptor, creationContext );
}
}
}

View File

@ -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<J> 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();
}
}

View File

@ -45,26 +45,6 @@ public class PojoInstantiatorImpl<J> extends AbstractPojoInstantiator {
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;
}

View File

@ -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<Object[]> valuesAccess, SessionFactoryImplementor sessionFactory);
}

View File

@ -13,5 +13,5 @@ public interface EmbeddableRepresentationStrategy extends ManagedTypeRepresentat
/**
* Create a delegate capable of instantiating instances of the represented type.
*/
<J> Instantiator<J> getInstantiator();
EmbeddableInstantiator getInstantiator();
}

View File

@ -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);
}

View File

@ -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

View File

@ -15,11 +15,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
* @author Steve Ebersole
*/
@Incubating
public interface Instantiator<J> {
/**
* 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

View File

@ -8,6 +8,7 @@ package org.hibernate.sql.results.graph.embeddable;
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 abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
compositeInstance = embeddableTypeDescriptor
.getRepresentationStrategy()
.getInstantiator()
.instantiate( rowProcessingState.getSession().getFactory() );
.instantiate( VALUE_ACCESS, rowProcessingState.getSession().getFactory() );
}
EmbeddableLoadingLogger.INSTANCE.debugf(
@ -155,6 +156,10 @@ 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) {
@ -211,7 +216,7 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
Object target = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor()
.getRepresentationStrategy()
.getInstantiator()
.instantiate( rowProcessingState.getSession().getFactory() );
.instantiate( VALUE_ACCESS, rowProcessingState.getSession().getFactory() );
embeddedModelPartDescriptor.getEmbeddableTypeDescriptor().setPropertyValues(
target,
resolvedValues

View File

@ -9,8 +9,6 @@ package org.hibernate.testing.boot;
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.BootstrapContext;
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 class BootstrapContextImpl implements BootstrapContext {
@Override
public ManagedTypeRepresentationResolver getRepresentationStrategySelector() {
return StandardManagedTypeRepresentationResolver.INSTANCE;
return ManagedTypeRepresentationResolverStandard.INSTANCE;
}
@Override