6 - SQM based on JPA type system, RuntimeModelCreationProcess

This commit is contained in:
Andrea Boriero 2019-05-29 20:53:04 +01:00
parent f52e305ffb
commit f20d36be40
15 changed files with 803 additions and 689 deletions

View File

@ -4,7 +4,7 @@
* 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.model.domain.internal;
package org.hibernate.metamodel.internal;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
@ -40,6 +40,11 @@ import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.PluralPersistentAttribute;
import org.hibernate.metamodel.model.domain.SimpleDomainType;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.model.domain.internal.EmbeddableTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MapMember;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.metamodel.model.domain.internal.PluralAttributeBuilder;
import org.hibernate.metamodel.model.domain.internal.SingularAttributeImpl;
import org.hibernate.property.access.internal.PropertyAccessMapImpl;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.tuple.entity.EntityMetamodel;
@ -293,9 +298,8 @@ public class AttributeFactory {
private EntityMetamodel getDeclarerEntityMetamodel(AbstractIdentifiableType<?> ownerType) {
final Type.PersistenceType persistenceType = ownerType.getPersistenceType();
if ( persistenceType == Type.PersistenceType.ENTITY ) {
return context.getSessionFactory()
.getMetamodel()
.entityPersister( ownerType.getTypeName() )
return context.getMetamodel()
.getEntityDescriptor( ownerType.getTypeName() )
.getEntityMetamodel();
}
else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS ) {

View File

@ -7,21 +7,48 @@
package org.hibernate.metamodel.internal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cache.spi.CacheImplementor;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Steve Ebersole
*/
public class InflightRuntimeMetamodel {
private static final EntityManagerMessageLogger log = HEMLogging.messageLogger( InflightRuntimeMetamodel.class );
private final TypeConfiguration typeConfiguration;
@ -29,28 +56,372 @@ public class InflightRuntimeMetamodel {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hibernate metamodel
private final Map<String, EntityPersister> entityPersisterMap = new HashMap<>();
private Map<Class, String> entityProxyInterfaceMap;
private Map<String, CollectionPersister> collectionPersisterMap;
private Map<String, Set<String>> collectionRolesByEntityParticipant;
private final Map<String, EntityPersister> entityPersisterMap = new ConcurrentHashMap<>();
private final Map<Class, String> entityProxyInterfaceMap = new ConcurrentHashMap<>();
private final Map<String, CollectionPersister> collectionPersisterMap = new ConcurrentHashMap<>();
private final Map<String, Set<String>> collectionRolesByEntityParticipant = new ConcurrentHashMap<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JPA metamodel
private final Map<String, EntityDomainType<?>> jpaEntityTypeMap = new HashMap<>();
private Map<Class, MappedSuperclassDomainType<?>> jpaMappedSuperclassTypeMap;
private Map<Class, EmbeddableDomainType<?>> embeddableDescriptorMap;
private final Map<String, EntityDomainType<?>> jpaEntityTypeMap = new ConcurrentHashMap<>();
private final Map<Class<?>, MappedSuperclassDomainType<?>> jpaMappedSuperclassTypeMap = new ConcurrentHashMap<>();
private Map<Class, EmbeddableDomainType<?>> jpaEmbeddableDescriptorMap = new ConcurrentHashMap<>();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Misc
private final Map<String, String> nameToImportNameMap = new HashMap<>();
private Set<EntityNameResolver> entityNameResolvers;
private final Set<EntityNameResolver> entityNameResolvers = new CopyOnWriteArraySet<>();
public InflightRuntimeMetamodel(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
public void processBootMetaModel(
MetadataImplementor bootMetamodel,
SqmCriteriaNodeBuilder criteriaBuilder,
CacheImplementor cacheImplementor,
PersisterFactory persisterFactory,
PersisterCreationContext persisterCreationContext,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting) {
processBootEntities(
bootMetamodel.getEntityBindings(),
cacheImplementor,
persisterFactory,
persisterCreationContext
);
processBootCollections(
bootMetamodel.getCollectionBindings(),
cacheImplementor,
persisterFactory,
persisterCreationContext
);
finishDomainMetamodelInitialization();
processJpa(
bootMetamodel,
criteriaBuilder,
jpaMetaModelPopulationSetting,
jpaStaticMetaModelPopulationSetting
);
}
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
public Map<String, EntityPersister> getEntityPersisterMap() {
return entityPersisterMap;
}
public Map<Class, String> getEntityProxyInterfaceMap() {
return entityProxyInterfaceMap;
}
public Map<String, CollectionPersister> getCollectionPersisterMap() {
return collectionPersisterMap;
}
public Map<String, Set<String>> getCollectionRolesByEntityParticipant() {
return collectionRolesByEntityParticipant;
}
public Map<String, EntityDomainType<?>> getJpaEntityTypeMap() {
return jpaEntityTypeMap;
}
public Map<Class<?>, MappedSuperclassDomainType<?>> getJpaMappedSuperclassTypeMap() {
return jpaMappedSuperclassTypeMap;
}
public Map<Class, EmbeddableDomainType<?>> getJpaEmbeddableDescriptorMap() {
return jpaEmbeddableDescriptorMap;
}
public Map<String, String> getNameToImportNameMap() {
return nameToImportNameMap;
}
public Set<EntityNameResolver> getEntityNameResolvers() {
return entityNameResolvers;
}
/**
* Get an entity mapping descriptor based on its Hibernate entity-name
*
* @throws IllegalArgumentException if the name does not refer to an entity
*/
public EntityPersister getEntityDescriptor(String entityName) {
final EntityPersister entityPersister = entityPersisterMap.get( entityName );
if ( entityPersister == null ) {
throw new IllegalArgumentException( "Unable to locate persister: " + entityName );
}
return entityPersister;
}
/**
* Find an entity mapping descriptor based on its Hibernate entity-name.
*
* @apiNote Returns {@code null} rather than throwing exception
*/
public EntityPersister findEntityDescriptor(String entityName) {
return entityPersisterMap.get( entityName );
}
private void processJpa(
MetadataImplementor bootMetamodel,
SqmCriteriaNodeBuilder criteriaBuilder,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting) {
if ( jpaMetaModelPopulationSetting != JpaMetaModelPopulationSetting.DISABLED ) {
MetadataContext context = new MetadataContext(
this,
criteriaBuilder,
bootMetamodel.getMappedSuperclassMappingsCopy(),
typeConfiguration,
jpaMetaModelPopulationSetting,
jpaStaticMetaModelPopulationSetting
);
for ( PersistentClass entityBinding : bootMetamodel.getEntityBindings() ) {
locateOrBuildEntityType( entityBinding, context );
}
handleUnusedMappedSuperclasses( context );
context.wrapUp();
this.nameToImportNameMap.putAll( bootMetamodel.getImports() );
this.jpaEntityTypeMap.putAll( context.getEntityTypesByEntityName() );
this.jpaMappedSuperclassTypeMap.putAll( context.getMappedSuperclassTypeMap() );
for ( EmbeddableDomainType<?> embeddable : context.getEmbeddableTypeSet() ) {
this.jpaEmbeddableDescriptorMap.put( embeddable.getJavaType(), embeddable );
}
}
}
private void processBootEntities(
java.util.Collection<PersistentClass> entityBindings,
CacheImplementor cacheImplementor,
PersisterFactory persisterFactory,
PersisterCreationContext persisterCreationContext) {
for ( final PersistentClass model : entityBindings ) {
final NavigableRole rootEntityRole = new NavigableRole( model.getRootClass().getEntityName() );
final EntityDataAccess accessStrategy = cacheImplementor.getEntityRegionAccess( rootEntityRole );
final NaturalIdDataAccess naturalIdAccessStrategy = cacheImplementor
.getNaturalIdCacheRegionAccessStrategy( rootEntityRole );
final EntityPersister cp = persisterFactory.createEntityPersister(
model,
accessStrategy,
naturalIdAccessStrategy,
persisterCreationContext
);
entityPersisterMap.put( model.getEntityName(), cp );
if ( cp.getConcreteProxyClass() != null
&& cp.getConcreteProxyClass().isInterface()
&& !Map.class.isAssignableFrom( cp.getConcreteProxyClass() )
&& cp.getMappedClass() != cp.getConcreteProxyClass() ) {
// IMPL NOTE : we exclude Map based proxy interfaces here because that should
// indicate MAP entity mode.0
if ( cp.getMappedClass().equals( cp.getConcreteProxyClass() ) ) {
// this part handles an odd case in the Hibernate test suite where we map an interface
// as the class and the proxy. I cannot think of a real life use case for that
// specific test, but..
log.debugf(
"Entity [%s] mapped same interface [%s] as class and proxy",
cp.getEntityName(),
cp.getMappedClass()
);
}
else {
final String old = entityProxyInterfaceMap.put( cp.getConcreteProxyClass(), cp.getEntityName() );
if ( old != null ) {
throw new HibernateException(
String.format(
Locale.ENGLISH,
"Multiple entities [%s, %s] named the same interface [%s] as their proxy which is not supported",
old,
cp.getEntityName(),
cp.getConcreteProxyClass().getName()
)
);
}
}
}
}
}
private void processBootCollections(
java.util.Collection<Collection> collectionBindings,
CacheImplementor cacheImplementor,
PersisterFactory persisterFactory,
PersisterCreationContext persisterCreationContext) {
for ( final Collection model : collectionBindings ) {
final NavigableRole navigableRole = new NavigableRole( model.getRole() );
final CollectionDataAccess accessStrategy = cacheImplementor.getCollectionRegionAccess(
navigableRole );
final CollectionPersister persister = persisterFactory.createCollectionPersister(
model,
accessStrategy,
persisterCreationContext
);
collectionPersisterMap.put( model.getRole(), persister );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isEntityType() && !indexType.isAnyType() ) {
String entityName = ( (EntityType) indexType ).getAssociatedEntityName();
Set<String> roles = collectionRolesByEntityParticipant.get( entityName );
if ( roles == null ) {
roles = new HashSet<>();
collectionRolesByEntityParticipant.put( entityName, roles );
}
roles.add( persister.getRole() );
}
Type elementType = persister.getElementType();
if ( elementType.isEntityType() && !elementType.isAnyType() ) {
String entityName = ( (EntityType) elementType ).getAssociatedEntityName();
Set<String> roles = collectionRolesByEntityParticipant.get( entityName );
if ( roles == null ) {
roles = new HashSet<>();
collectionRolesByEntityParticipant.put( entityName, roles );
}
roles.add( persister.getRole() );
}
}
}
private void finishDomainMetamodelInitialization() {
// after *all* persisters and named queries are registered
entityPersisterMap.values().forEach( EntityPersister::generateEntityDefinition );
for ( EntityPersister persister : entityPersisterMap.values() ) {
persister.postInstantiate();
registerEntityNameResolvers( persister, entityNameResolvers );
}
collectionPersisterMap.values().forEach( CollectionPersister::postInstantiate );
}
private static void registerEntityNameResolvers(
EntityPersister persister,
Set<EntityNameResolver> entityNameResolvers) {
if ( persister.getEntityMetamodel() == null || persister.getEntityMetamodel().getTuplizer() == null ) {
return;
}
registerEntityNameResolvers( persister.getEntityMetamodel().getTuplizer(), entityNameResolvers );
}
private static void registerEntityNameResolvers(
EntityTuplizer tuplizer,
Set<EntityNameResolver> entityNameResolvers) {
EntityNameResolver[] resolvers = tuplizer.getEntityNameResolvers();
if ( resolvers == null ) {
return;
}
for ( EntityNameResolver resolver : resolvers ) {
entityNameResolvers.add( resolver );
}
}
private static void handleUnusedMappedSuperclasses(MetadataContext context) {
final Set<MappedSuperclass> unusedMappedSuperclasses = context.getUnusedMappedSuperclasses();
if ( !unusedMappedSuperclasses.isEmpty() ) {
for ( MappedSuperclass mappedSuperclass : unusedMappedSuperclasses ) {
log.unusedMappedSuperclass( mappedSuperclass.getMappedClass().getName() );
locateOrBuildMappedSuperclassType( mappedSuperclass, context );
}
}
}
private static MappedSuperclassDomainType<?> locateOrBuildMappedSuperclassType(
MappedSuperclass mappedSuperclass,
MetadataContext context) {
MappedSuperclassDomainType<?> mappedSuperclassType = context.locateMappedSuperclassType( mappedSuperclass );
if ( mappedSuperclassType == null ) {
mappedSuperclassType = buildMappedSuperclassType( mappedSuperclass, context );
}
return mappedSuperclassType;
}
@SuppressWarnings("unchecked")
private static MappedSuperclassTypeImpl<?> buildMappedSuperclassType(
MappedSuperclass mappedSuperclass,
MetadataContext context) {
final MappedSuperclass superMappedSuperclass = mappedSuperclass.getSuperMappedSuperclass();
IdentifiableDomainType<?> superType = superMappedSuperclass == null
? null
: locateOrBuildMappedSuperclassType( superMappedSuperclass, context );
//no mappedSuperclass, check for a super entity
if ( superType == null ) {
final PersistentClass superPersistentClass = mappedSuperclass.getSuperPersistentClass();
superType = superPersistentClass == null
? null
: locateOrBuildEntityType( superPersistentClass, context );
}
final JavaTypeDescriptor javaTypeDescriptor = context.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( mappedSuperclass.getMappedClass() );
MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl(
javaTypeDescriptor,
mappedSuperclass,
superType
);
context.registerMappedSuperclassType( mappedSuperclass, mappedSuperclassType );
return mappedSuperclassType;
}
private static EntityDomainType<?> locateOrBuildEntityType(
PersistentClass persistentClass,
MetadataContext context) {
EntityDomainType<?> entityType = context.locateEntityType( persistentClass );
if ( entityType == null ) {
entityType = buildEntityType( persistentClass, context );
}
return entityType;
}
@SuppressWarnings("unchecked")
private static EntityTypeImpl<?> buildEntityType(PersistentClass persistentClass, MetadataContext context) {
final Class javaType = persistentClass.getMappedClass();
context.pushEntityWorkedOn( persistentClass );
final MappedSuperclass superMappedSuperclass = persistentClass.getSuperMappedSuperclass();
IdentifiableDomainType<?> superType = superMappedSuperclass == null
? null
: locateOrBuildMappedSuperclassType( superMappedSuperclass, context );
//no mappedSuperclass, check for a super entity
if ( superType == null ) {
final PersistentClass superPersistentClass = persistentClass.getSuperclass();
superType = superPersistentClass == null
? null
: locateOrBuildEntityType( superPersistentClass, context );
}
final JavaTypeDescriptor javaTypeDescriptor = context.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( javaType );
EntityTypeImpl entityType = new EntityTypeImpl(
javaTypeDescriptor,
superType,
persistentClass
);
context.registerEntityType( persistentClass, entityType );
context.popEntityWorkedOn( persistentClass );
return entityType;
}
}

View File

@ -4,7 +4,7 @@
* 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.model.domain.internal;
package org.hibernate.metamodel.internal;
import java.lang.reflect.Field;
import java.util.ArrayList;
@ -17,13 +17,10 @@ import java.util.Map;
import java.util.Set;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.IdentifiableType;
import javax.persistence.metamodel.MappedSuperclassType;
import javax.persistence.metamodel.Metamodel;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.internal.util.ReflectHelper;
@ -33,20 +30,20 @@ import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.BasicDomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.model.domain.PersistentAttribute;
import org.hibernate.metamodel.model.domain.SingularPersistentAttribute;
import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.metamodel.model.domain.internal.AttributeContainer;
import org.hibernate.metamodel.model.domain.internal.BasicTypeImpl;
import org.hibernate.metamodel.model.domain.internal.DomainMetamodelImpl;
import org.hibernate.metamodel.model.domain.internal.EntityTypeImpl;
import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
import org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
import org.hibernate.type.spi.TypeConfiguration;
@ -90,10 +87,10 @@ class MetadataContext {
* Stack of PersistentClass being process. Last in the list is the highest in the stack.
*/
private List<PersistentClass> stackOfPersistentClassesBeingProcessed = new ArrayList<>();
private DomainMetamodel metamodel;
private InflightRuntimeMetamodel metamodel;
public MetadataContext(
DomainMetamodel metamodel,
InflightRuntimeMetamodel metamodel,
SqmCriteriaNodeBuilder criteriaBuilder,
Set<MappedSuperclass> mappedSuperclasses,
TypeConfiguration typeConfiguration,
@ -120,7 +117,7 @@ class MetadataContext {
return typeConfiguration.getJavaTypeDescriptorRegistry();
}
DomainMetamodel getMetamodel() {
InflightRuntimeMetamodel getMetamodel() {
return metamodel;
}
@ -141,9 +138,9 @@ class MetadataContext {
return new HashSet<>( embeddables.values() );
}
public Map<Class<?>, MappedSuperclassType<?>> getMappedSuperclassTypeMap() {
public Map<Class<?>, MappedSuperclassDomainType<?>> getMappedSuperclassTypeMap() {
// we need to actually build this map...
final Map<Class<?>, MappedSuperclassType<?>> mappedSuperClassTypeMap = CollectionHelper.mapOfSize(
final Map<Class<?>, MappedSuperclassDomainType<?>> mappedSuperClassTypeMap = CollectionHelper.mapOfSize(
mappedSuperclassByMappedSuperclassMapping.size()
);
@ -267,7 +264,7 @@ class MetadataContext {
}
final PersistentAttribute attribute = attributeFactory.buildAttribute( jpaMapping, property );
if ( attribute != null ) {
( ( AttributeContainer) jpaMapping ).getInFlightAccess().addAttribute( attribute );
( (AttributeContainer) jpaMapping ).getInFlightAccess().addAttribute( attribute );
}
}

View File

@ -6,12 +6,28 @@
*/
package org.hibernate.metamodel.internal;
import org.hibernate.NotYetImplementedFor6Exception;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cache.cfg.internal.DomainDataRegionConfigImpl;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.internal.DomainMetamodelImpl;
import org.hibernate.metamodel.model.domain.internal.JpaMetamodelImpl;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.spi.PersisterFactory;
import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting.determineJpaMetaModelPopulationSetting;
@ -19,10 +35,9 @@ import static org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetti
* Responsible for interpreting the Hibernate boot metamodel into
* its runtime metamodel
*
* @author Steve Ebersole
* @see org.hibernate.boot.model
* @see org.hibernate.metamodel
*
* @author Steve Ebersole
*/
public class RuntimeModelCreationProcess {
@ -76,31 +91,131 @@ public class RuntimeModelCreationProcess {
SessionFactoryImplementor sessionFactory,
BootstrapContext bootstrapContext,
MetadataBuildingContext metadataBuildingContext,
MetadataImplementor bootMetamodel) {
return new RuntimeModelCreationProcess( sessionFactory, bootstrapContext, metadataBuildingContext ).execute();
MetadataImplementor bootMetamodel,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) {
return new RuntimeModelCreationProcess(
sessionFactory,
bootstrapContext,
metadataBuildingContext,
bootMetamodel,
jpaMetaModelPopulationSetting
).execute();
}
private final SessionFactoryImplementor sessionFactory;
private final BootstrapContext bootstrapContext;
private final MetadataBuildingContext metadataBuildingContext;
private final MetadataImplementor bootMetamodel;
private final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting;
private JpaMetamodel jpaMetamodel;
private MetamodelImplementor domainMetamodel;
public RuntimeModelCreationProcess(
SessionFactoryImplementor sessionFactory,
BootstrapContext bootstrapContext,
MetadataBuildingContext metadataBuildingContext) {
MetadataBuildingContext metadataBuildingContext,
MetadataImplementor bootMetamodel,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) {
this.sessionFactory = sessionFactory;
this.bootstrapContext = bootstrapContext;
this.metadataBuildingContext = metadataBuildingContext;
this.bootMetamodel = bootMetamodel;
this.jpaMetaModelPopulationSetting = jpaMetaModelPopulationSetting;
}
public MetamodelImplementor execute() {
final PersisterCreationContext persisterCreationContext = new PersisterCreationContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public MetadataImplementor getMetadata() {
return bootMetamodel;
}
};
final PersisterFactory persisterFactory = sessionFactory.getServiceRegistry()
.getService( PersisterFactory.class );
final InflightRuntimeMetamodel inflightRuntimeMetamodel = new InflightRuntimeMetamodel( bootstrapContext.getTypeConfiguration() );
final JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting = determineJpaMetaModelPopulationSetting(
sessionFactory.getProperties()
primeSecondLevelCacheRegions( bootMetamodel );
inflightRuntimeMetamodel.processBootMetaModel(
bootMetamodel,
sessionFactory.getQueryEngine().getCriteriaBuilder(),
sessionFactory.getCache(),
persisterFactory,
persisterCreationContext,
jpaMetaModelPopulationSetting,
determineJpaMetaModelPopulationSetting(
sessionFactory.getProperties() )
);
throw new NotYetImplementedFor6Exception();
this.jpaMetamodel = new JpaMetamodelImpl(
inflightRuntimeMetamodel,
bootMetamodel.getNamedEntityGraphs().values()
);
this.domainMetamodel = new DomainMetamodelImpl( sessionFactory, inflightRuntimeMetamodel, this.jpaMetamodel );
return domainMetamodel;
}
private void primeSecondLevelCacheRegions(MetadataImplementor mappingMetadata) {
final Map<String, DomainDataRegionConfigImpl.Builder> regionConfigBuilders = new ConcurrentHashMap<>();
// todo : ultimately this code can be made more efficient when we have a better intrinsic understanding of the hierarchy as a whole
for ( PersistentClass bootEntityDescriptor : mappingMetadata.getEntityBindings() ) {
final AccessType accessType = AccessType.fromExternalName( bootEntityDescriptor.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
if ( bootEntityDescriptor.isCached() ) {
regionConfigBuilders.computeIfAbsent(
bootEntityDescriptor.getRootClass().getCacheRegionName(),
DomainDataRegionConfigImpl.Builder::new
)
.addEntityConfig( bootEntityDescriptor, accessType );
}
if ( RootClass.class.isInstance( bootEntityDescriptor )
&& bootEntityDescriptor.hasNaturalId()
&& bootEntityDescriptor.getNaturalIdCacheRegionName() != null ) {
regionConfigBuilders.computeIfAbsent(
bootEntityDescriptor.getNaturalIdCacheRegionName(),
DomainDataRegionConfigImpl.Builder::new
)
.addNaturalIdConfig( (RootClass) bootEntityDescriptor, accessType );
}
}
}
for ( Collection collection : mappingMetadata.getCollectionBindings() ) {
final AccessType accessType = AccessType.fromExternalName( collection.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
regionConfigBuilders.computeIfAbsent(
collection.getCacheRegionName(),
DomainDataRegionConfigImpl.Builder::new
)
.addCollectionConfig( collection, accessType );
}
}
final Set<DomainDataRegionConfig> regionConfigs;
if ( regionConfigBuilders.isEmpty() ) {
regionConfigs = Collections.emptySet();
}
else {
regionConfigs = new HashSet<>();
for ( DomainDataRegionConfigImpl.Builder builder : regionConfigBuilders.values() ) {
regionConfigs.add( builder.build() );
}
}
sessionFactory.getCache().prime( regionConfigs );
}
}

View File

@ -12,22 +12,23 @@ import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
* @author Steve Ebersole
*/
public abstract class AbstractDomainType<J> implements SimpleDomainType<J> {
private final JpaMetamodel jpaMetamodel;
private JpaMetamodel jpaMetamodel;
private final JavaTypeDescriptor<J> javaTypeDescriptor;
@SuppressWarnings("WeakerAccess")
public AbstractDomainType(
JavaTypeDescriptor<J> javaTypeDescriptor,
JpaMetamodel jpaMetamodel) {
public AbstractDomainType(JavaTypeDescriptor<J> javaTypeDescriptor) {
this.javaTypeDescriptor = javaTypeDescriptor;
this.jpaMetamodel = jpaMetamodel;
}
protected JpaMetamodel jpaMetamodel() {
return jpaMetamodel;
}
public void injectJpaMetamodel(JpaMetamodel jpaMetamodel){
this.jpaMetamodel = jpaMetamodel;
}
@Override
public JavaTypeDescriptor<J> getExpressableJavaTypeDescriptor() {
return javaTypeDescriptor;

View File

@ -45,9 +45,8 @@ public abstract class AbstractIdentifiableType<J>
IdentifiableDomainType<? super J> superType,
boolean hasIdClass,
boolean hasIdentifierProperty,
boolean versioned,
JpaMetamodel jpaMetamodel) {
super( typeName, javaTypeDescriptor, superType, jpaMetamodel );
boolean versioned) {
super( typeName, javaTypeDescriptor, superType );
this.hasIdClass = hasIdClass;
this.hasIdentifierProperty = hasIdentifierProperty;
this.isVersioned = versioned;

View File

@ -48,9 +48,8 @@ public abstract class AbstractManagedType<J>
protected AbstractManagedType(
String hibernateTypeName,
JavaTypeDescriptor<J> javaTypeDescriptor,
ManagedDomainType<? super J> superType,
JpaMetamodel jpaMetamodel) {
super( javaTypeDescriptor, jpaMetamodel );
ManagedDomainType<? super J> superType) {
super( javaTypeDescriptor );
this.hibernateTypeName = hibernateTypeName;
this.superType = superType;

View File

@ -9,14 +9,10 @@ package org.hibernate.metamodel.model.domain.internal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;
import javax.persistence.EntityGraph;
import javax.persistence.metamodel.EmbeddableType;
@ -24,44 +20,26 @@ import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import org.hibernate.EntityNameResolver;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.UnknownEntityTypeException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cache.cfg.internal.DomainDataRegionConfigImpl;
import org.hibernate.cache.cfg.spi.DomainDataRegionConfig;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cache.spi.access.CollectionDataAccess;
import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.NaturalIdDataAccess;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.graph.RootGraph;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.NavigableRole;
import org.hibernate.metamodel.internal.InflightRuntimeMetamodel;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.metamodel.spi.MetamodelImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.spi.PersisterFactory;
import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.type.AssociationType;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -84,7 +62,7 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JpaMetamodel
private final JpaMetamodelImpl jpaMetamodel;
private final JpaMetamodel jpaMetamodel;
// private final Map<Class<?>, EntityDomainType<?>> jpaEntityTypeMap = new ConcurrentHashMap<>();
// private final Map<String, EntityDomainType<?>> jpaEntityTypesByEntityName = new ConcurrentHashMap<>();
@ -96,15 +74,15 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RuntimeModel
private final Map<String, EntityPersister> entityPersisterMap = new ConcurrentHashMap<>();
private final Map<String, CollectionPersister> collectionPersisterMap = new ConcurrentHashMap<>();
private final Map<String, Set<String>> collectionRolesByEntityParticipant = new ConcurrentHashMap<>();
private final Map<String, EntityPersister> entityPersisterMap;
private final Map<String, CollectionPersister> collectionPersisterMap;
private final Map<String, Set<String>> collectionRolesByEntityParticipant;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DomainMetamodel
private final ConcurrentMap<EntityNameResolver, Object> entityNameResolvers = new ConcurrentHashMap<>();
private final Set<EntityNameResolver> entityNameResolvers;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -143,254 +121,25 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
private final Map<String, String[]> implementorsCache = new ConcurrentHashMap<>();
public DomainMetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
public DomainMetamodelImpl(
SessionFactoryImplementor sessionFactory,
InflightRuntimeMetamodel runtimeMetamodel,
JpaMetamodel jpaMetamodel) {
this.sessionFactory = sessionFactory;
this.typeConfiguration = typeConfiguration;
this.jpaMetamodel = new JpaMetamodelImpl( typeConfiguration );
this.jpaMetamodel = jpaMetamodel;
this.typeConfiguration = runtimeMetamodel.getTypeConfiguration();
this.entityPersisterMap = runtimeMetamodel.getEntityPersisterMap();
this.collectionPersisterMap = runtimeMetamodel.getCollectionPersisterMap();
this.collectionRolesByEntityParticipant = runtimeMetamodel.getCollectionRolesByEntityParticipant();
this.entityNameResolvers = runtimeMetamodel.getEntityNameResolvers();
}
/**
* Prepare the metamodel using the information from the collection of Hibernate
* {@link PersistentClass} models
*
* @param mappingMetadata The mapping information
* @param jpaMetaModelPopulationSetting Should the JPA Metamodel be built as well?
*/
public void initialize(
MetadataImplementor mappingMetadata,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) {
primeSecondLevelCacheRegions( mappingMetadata );
final PersisterCreationContext persisterCreationContext = new PersisterCreationContext() {
@Override
public SessionFactoryImplementor getSessionFactory() {
return sessionFactory;
}
@Override
public MetadataImplementor getMetadata() {
return mappingMetadata;
}
};
final PersisterFactory persisterFactory = sessionFactory.getServiceRegistry()
.getService( PersisterFactory.class );
for ( final PersistentClass model : mappingMetadata.getEntityBindings() ) {
final NavigableRole rootEntityRole = new NavigableRole( model.getRootClass().getEntityName() );
final EntityDataAccess accessStrategy = sessionFactory.getCache().getEntityRegionAccess( rootEntityRole );
final NaturalIdDataAccess naturalIdAccessStrategy = sessionFactory.getCache()
.getNaturalIdCacheRegionAccessStrategy( rootEntityRole );
final EntityPersister cp = persisterFactory.createEntityPersister(
model,
accessStrategy,
naturalIdAccessStrategy,
persisterCreationContext
);
entityPersisterMap.put( model.getEntityName(), cp );
if ( cp.getConcreteProxyClass() != null
&& cp.getConcreteProxyClass().isInterface()
&& !Map.class.isAssignableFrom( cp.getConcreteProxyClass() )
&& cp.getMappedClass() != cp.getConcreteProxyClass() ) {
// IMPL NOTE : we exclude Map based proxy interfaces here because that should
// indicate MAP entity mode.0
if ( cp.getMappedClass().equals( cp.getConcreteProxyClass() ) ) {
// this part handles an odd case in the Hibernate test suite where we map an interface
// as the class and the proxy. I cannot think of a real life use case for that
// specific test, but..
log.debugf(
"Entity [%s] mapped same interface [%s] as class and proxy",
cp.getEntityName(),
cp.getMappedClass()
);
}
else {
final String old = entityProxyInterfaceMap.put( cp.getConcreteProxyClass(), cp.getEntityName() );
if ( old != null ) {
throw new HibernateException(
String.format(
Locale.ENGLISH,
"Multiple entities [%s, %s] named the same interface [%s] as their proxy which is not supported",
old,
cp.getEntityName(),
cp.getConcreteProxyClass().getName()
)
);
}
}
}
}
for ( final Collection model : mappingMetadata.getCollectionBindings() ) {
final NavigableRole navigableRole = new NavigableRole( model.getRole() );
final CollectionDataAccess accessStrategy = sessionFactory.getCache().getCollectionRegionAccess(
navigableRole );
final CollectionPersister persister = persisterFactory.createCollectionPersister(
model,
accessStrategy,
persisterCreationContext
);
collectionPersisterMap.put( model.getRole(), persister );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
String entityName = ( (AssociationType) indexType ).getAssociatedEntityName( sessionFactory );
Set<String> roles = collectionRolesByEntityParticipant.get( entityName );
if ( roles == null ) {
roles = new HashSet<>();
collectionRolesByEntityParticipant.put( entityName, roles );
}
roles.add( persister.getRole() );
}
Type elementType = persister.getElementType();
if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
String entityName = ( (AssociationType) elementType ).getAssociatedEntityName( sessionFactory );
Set<String> roles = collectionRolesByEntityParticipant.get( entityName );
if ( roles == null ) {
roles = new HashSet<>();
collectionRolesByEntityParticipant.put( entityName, roles );
}
roles.add( persister.getRole() );
}
}
// after *all* persisters and named queries are registered
entityPersisterMap.values().forEach( EntityPersister::generateEntityDefinition );
for ( EntityPersister persister : entityPersisterMap.values() ) {
persister.postInstantiate();
registerEntityNameResolvers( persister, entityNameResolvers );
}
collectionPersisterMap.values().forEach( CollectionPersister::postInstantiate );
jpaMetamodel.initialize(
this,
mappingMetadata,
sessionFactory.getQueryEngine().getCriteriaBuilder(),
jpaMetaModelPopulationSetting,
JpaStaticMetaModelPopulationSetting.determineJpaMetaModelPopulationSetting( sessionFactory.getProperties() )
);
}
private void primeSecondLevelCacheRegions(MetadataImplementor mappingMetadata) {
final Map<String, DomainDataRegionConfigImpl.Builder> regionConfigBuilders = new ConcurrentHashMap<>();
// todo : ultimately this code can be made more efficient when we have a better intrinsic understanding of the hierarchy as a whole
for ( PersistentClass bootEntityDescriptor : mappingMetadata.getEntityBindings() ) {
final AccessType accessType = AccessType.fromExternalName( bootEntityDescriptor.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
if ( bootEntityDescriptor.isCached() ) {
regionConfigBuilders.computeIfAbsent(
bootEntityDescriptor.getRootClass().getCacheRegionName(),
DomainDataRegionConfigImpl.Builder::new
)
.addEntityConfig( bootEntityDescriptor, accessType );
}
if ( RootClass.class.isInstance( bootEntityDescriptor )
&& bootEntityDescriptor.hasNaturalId()
&& bootEntityDescriptor.getNaturalIdCacheRegionName() != null ) {
regionConfigBuilders.computeIfAbsent(
bootEntityDescriptor.getNaturalIdCacheRegionName(),
DomainDataRegionConfigImpl.Builder::new
)
.addNaturalIdConfig( (RootClass) bootEntityDescriptor, accessType );
}
}
}
for ( Collection collection : mappingMetadata.getCollectionBindings() ) {
final AccessType accessType = AccessType.fromExternalName( collection.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
regionConfigBuilders.computeIfAbsent(
collection.getCacheRegionName(),
DomainDataRegionConfigImpl.Builder::new
)
.addCollectionConfig( collection, accessType );
}
}
final Set<DomainDataRegionConfig> regionConfigs;
if ( regionConfigBuilders.isEmpty() ) {
regionConfigs = Collections.emptySet();
}
else {
regionConfigs = new HashSet<>();
for ( DomainDataRegionConfigImpl.Builder builder : regionConfigBuilders.values() ) {
regionConfigs.add( builder.build() );
}
}
getSessionFactory().getCache().prime( regionConfigs );
}
@Override
public java.util.Collection<EntityNameResolver> getEntityNameResolvers() {
return entityNameResolvers.keySet();
return entityNameResolvers;
}
private static void registerEntityNameResolvers(
EntityPersister persister,
Map<EntityNameResolver, Object> entityNameResolvers) {
if ( persister.getEntityMetamodel() == null || persister.getEntityMetamodel().getTuplizer() == null ) {
return;
}
registerEntityNameResolvers( persister.getEntityMetamodel().getTuplizer(), entityNameResolvers );
}
private static void registerEntityNameResolvers(
EntityTuplizer tuplizer,
Map<EntityNameResolver, Object> entityNameResolvers) {
EntityNameResolver[] resolvers = tuplizer.getEntityNameResolvers();
if ( resolvers == null ) {
return;
}
for ( EntityNameResolver resolver : resolvers ) {
entityNameResolvers.put( resolver, ENTITY_NAME_RESOLVER_MAP_VALUE );
}
}
// /**
// * Instantiate the metamodel.
// *
// * @param entityNameResolvers
// * @param entities The entity mappings.
// * @param embeddables The embeddable (component) mappings.
// * @param mappedSuperclassTypeMap The {@link javax.persistence.MappedSuperclass} mappings
// */
// private MetamodelImpl(
// SessionFactoryImplementor sessionFactory,
// Map<String, String> imports,
// Map<String, EntityPersister> entityPersisterMap,
// Map<Class, String> entityProxyInterfaceMap,
// ConcurrentHashMap<EntityNameResolver, Object> entityNameResolvers,
// Map<String, CollectionPersister> collectionPersisterMap,
// Map<String, Set<String>> collectionRolesByEntityParticipant,
// Map<Class<?>, EntityTypeImpl<?>> entities,
// Map<Class<?>, EmbeddableTypeImpl<?>> embeddables,
// Map<Class<?>, MappedSuperclassType<?>> mappedSuperclassTypeMap,
// Map<String, EntityTypeImpl<?>> entityTypesByEntityName) {
// this.sessionFactory = sessionFactory;
// this.imports = imports;
// this.entityPersisterMap = entityPersisterMap;
// this.entityProxyInterfaceMap = entityProxyInterfaceMap;
// this.entityNameResolvers = entityNameResolvers;
// this.collectionPersisterMap = collectionPersisterMap;
// this.collectionRolesByEntityParticipant = collectionRolesByEntityParticipant;
// this.entities = entities;
// this.embeddables = embeddables;
// this.mappedSuperclassTypeMap = mappedSuperclassTypeMap;
// this.entityTypesByEntityName = entityTypesByEntityName;
// }
@Override
public TypeConfiguration getTypeConfiguration() {
@ -404,16 +153,16 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
@Override
public EntityPersister determineEntityPersister(Object entity) {
return findEntityDescriptor(entity.getClass());
return findEntityDescriptor( entity.getClass() );
}
@Override
public void visitEntityDescriptors(Consumer<EntityPersister> action){
public void visitEntityDescriptors(Consumer<EntityPersister> action) {
entityPersisterMap.values().forEach( action );
}
@Override
public EntityPersister getEntityDescriptor(String entityName){
public EntityPersister getEntityDescriptor(String entityName) {
final EntityPersister entityPersister = entityPersisterMap.get( entityName );
if ( entityPersister == null ) {
throw new IllegalArgumentException( "Unable to locate persister: " + entityName );
@ -422,12 +171,12 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
}
@Override
public EntityPersister findEntityDescriptor(String entityName){
public EntityPersister findEntityDescriptor(String entityName) {
return entityPersisterMap.get( entityName );
}
@Override
public EntityPersister findEntityDescriptor(Class entityJavaType){
public EntityPersister findEntityDescriptor(Class entityJavaType) {
return findEntityDescriptor( entityJavaType.getName() );
}
@ -437,7 +186,7 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
}
@Override
public EntityPersister getEntityDescriptor(Class entityJavaType){
public EntityPersister getEntityDescriptor(Class entityJavaType) {
EntityPersister entityPersister = entityPersisterMap.get( entityJavaType.getName() );
if ( entityPersister == null ) {
String mappedEntityName = entityProxyInterfaceMap.get( entityJavaType );
@ -454,7 +203,7 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
}
@Override
public EntityPersister locateEntityDescriptor(Class byClass){
public EntityPersister locateEntityDescriptor(Class byClass) {
EntityPersister entityPersister = entityPersisterMap.get( byClass.getName() );
if ( entityPersister == null ) {
String mappedEntityName = entityProxyInterfaceMap.get( byClass );
@ -579,21 +328,21 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
}
@Override
public void visitCollectionDescriptors(Consumer<CollectionPersister> action){
public void visitCollectionDescriptors(Consumer<CollectionPersister> action) {
collectionPersisterMap.values().forEach( action );
}
@Override
public CollectionPersister getCollectionDescriptor(String role){
public CollectionPersister getCollectionDescriptor(String role) {
CollectionPersister collectionPersister = collectionPersisterMap.get( role );
if(collectionPersister == null){
if ( collectionPersister == null ) {
throw new IllegalArgumentException( "Unable to locate persister: " + role );
}
return collectionPersister;
}
@Override
public CollectionPersister findCollectionDescriptor(String role){
public CollectionPersister findCollectionDescriptor(String role) {
return collectionPersisterMap.get( role );
}
@ -635,7 +384,7 @@ public class DomainMetamodelImpl implements DomainMetamodel, MetamodelImplemento
}
@Override
public RootGraph<?> findNamedGraph(String name){
public RootGraph<?> findNamedGraph(String name) {
return findEntityGraphByName( name );
}

View File

@ -28,7 +28,7 @@ public class EmbeddableTypeImpl<J>
implements EmbeddableDomainType<J>, Serializable {
public EmbeddableTypeImpl(JavaTypeDescriptor<J> javaTypeDescriptor, NodeBuilder nodeBuilder) {
super( javaTypeDescriptor.getJavaType().getName(), javaTypeDescriptor, null, nodeBuilder.getDomainModel() );
super( javaTypeDescriptor.getJavaType().getName(), javaTypeDescriptor, null );
}
public EmbeddableTypeImpl(
@ -37,9 +37,11 @@ public class EmbeddableTypeImpl<J>
//noinspection unchecked
super(
name,
(JavaTypeDescriptor) nodeBuilder.getDomainModel().getTypeConfiguration().getJavaTypeDescriptorRegistry().getDescriptor( Map.class ),
null,
nodeBuilder.getDomainModel()
(JavaTypeDescriptor) nodeBuilder.getDomainModel()
.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( Map.class ),
null
);
}

View File

@ -36,16 +36,14 @@ public class EntityTypeImpl<J>
public EntityTypeImpl(
JavaTypeDescriptor<J> javaTypeDescriptor,
IdentifiableDomainType<? super J> superType,
PersistentClass persistentClass,
JpaMetamodel jpaMetamodel) {
PersistentClass persistentClass) {
super(
persistentClass.getEntityName(),
javaTypeDescriptor,
superType,
persistentClass.getDeclaredIdentifierMapper() != null || ( superType != null && superType.hasIdClass() ),
persistentClass.hasIdentifierProperty(),
persistentClass.isVersioned(),
jpaMetamodel
persistentClass.isVersioned()
);
this.jpaEntityName = persistentClass.getJpaEntityName();
}

View File

@ -12,9 +12,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
import javax.persistence.EntityGraph;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
@ -23,11 +21,9 @@ import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EmbeddableType;
import javax.persistence.metamodel.EntityType;
import javax.persistence.metamodel.ManagedType;
import javax.persistence.metamodel.MappedSuperclassType;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.annotations.NamedEntityGraphDefinition;
import org.hibernate.graph.internal.RootGraphImpl;
import org.hibernate.graph.spi.AttributeNodeImplementor;
@ -38,20 +34,14 @@ import org.hibernate.internal.EntityManagerMessageLogger;
import org.hibernate.internal.HEMLogging;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.internal.JpaMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.JpaStaticMetaModelPopulationSetting;
import org.hibernate.metamodel.internal.InflightRuntimeMetamodel;
import org.hibernate.metamodel.model.domain.AbstractDomainType;
import org.hibernate.metamodel.model.domain.EmbeddableDomainType;
import org.hibernate.metamodel.model.domain.EntityDomainType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.ManagedDomainType;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.metamodel.spi.DomainMetamodel;
import org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;
import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -63,57 +53,233 @@ public class JpaMetamodelImpl implements JpaMetamodel {
private final TypeConfiguration typeConfiguration;
private final Map<String, EntityDomainType<?>> entityDescriptorMap = new ConcurrentHashMap<>();
private final Map<Class, EntityDomainType<?>> strictEntityDescriptorMap = new ConcurrentHashMap<>();
private final Map<String, EntityDomainType<?>> entityDescriptorMap;
private final Map<Class<?>, MappedSuperclassType<?>> mappedSuperclassTypeMap = new ConcurrentHashMap<>();
private final Map<Class<?>, MappedSuperclassDomainType<?>> mappedSuperclassTypeMap;
private final Map<Class, EmbeddableDomainType<?>> embeddableDescriptorMap = new ConcurrentHashMap<>();
private final Map<Class, EmbeddableDomainType<?>> embeddableDescriptorMap;
private final Map<String, String> nameToImportNameMap = new ConcurrentHashMap<>();
private final Map<String, String> nameToImportNameMap;
private final transient Map<String, RootGraphImplementor> entityGraphMap = new ConcurrentHashMap<>();
private final Map<Class, SqmPolymorphicRootDescriptor<?>> polymorphicEntityReferenceMap = new ConcurrentHashMap<>();
public JpaMetamodelImpl(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
private final Map<Class, String> entityProxyInterfaceMap;
public JpaMetamodelImpl(
InflightRuntimeMetamodel runtimeMetamodel,
java.util.Collection<NamedEntityGraphDefinition> namedEntityGraphDefinitions) {
this.typeConfiguration = runtimeMetamodel.getTypeConfiguration();
entityDescriptorMap = runtimeMetamodel.getJpaEntityTypeMap();
mappedSuperclassTypeMap = runtimeMetamodel.getJpaMappedSuperclassTypeMap();
embeddableDescriptorMap = runtimeMetamodel.getJpaEmbeddableDescriptorMap();
entityDescriptorMap.values()
.forEach( domainType -> ( (AbstractDomainType) domainType ).injectJpaMetamodel( this ) );
mappedSuperclassTypeMap.values().forEach( domainType -> ( (AbstractDomainType) domainType ).injectJpaMetamodel(
this ) );
entityDescriptorMap.values()
.forEach( domainType -> ( (AbstractDomainType) domainType ).injectJpaMetamodel( this ) );
nameToImportNameMap = runtimeMetamodel.getNameToImportNameMap();
entityProxyInterfaceMap = runtimeMetamodel.getEntityProxyInterfaceMap();
applyNamedEntityGraphs( namedEntityGraphDefinitions );
}
public void initialize(
DomainMetamodel metamodel,
MetadataImplementor mappingMetadata,
SqmCriteriaNodeBuilder criteriaBuilder,
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting,
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting) {
if ( jpaMetaModelPopulationSetting != JpaMetaModelPopulationSetting.DISABLED ) {
MetadataContext context = new MetadataContext(
metamodel,
criteriaBuilder,
mappingMetadata.getMappedSuperclassMappingsCopy(),
typeConfiguration,
jpaMetaModelPopulationSetting,
jpaStaticMetaModelPopulationSetting
);
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
for ( PersistentClass entityBinding : mappingMetadata.getEntityBindings() ) {
locateOrBuildEntityType( entityBinding, context );
}
handleUnusedMappedSuperclasses( context );
@Override
public <X> EntityDomainType<X> entity(String entityName) {
//noinspection unchecked
return (EntityDomainType) entityDescriptorMap.get( entityName );
}
context.wrapUp();
@Override
public <X> EntityDomainType<X> resolveHqlEntityReference(String entityName) {
final String rename = resolveImportedName( entityName );
if ( rename != null ) {
entityName = rename;
}
this.nameToImportNameMap.putAll( mappingMetadata.getImports() );
final EntityDomainType<X> entityDescriptor = entity( entityName );
if ( entityDescriptor != null ) {
return entityDescriptor;
}
this.strictEntityDescriptorMap.putAll( context.getEntityTypeMap() );
this.entityDescriptorMap.putAll( context.getEntityTypesByEntityName() );
this.mappedSuperclassTypeMap.putAll( context.getMappedSuperclassTypeMap() );
final Class<X> requestedClass = resolveRequestedClass( entityName );
if ( requestedClass != null ) {
return resolveEntityReference( requestedClass );
}
for ( EmbeddableDomainType<?> embeddable : context.getEmbeddableTypeSet() ) {
this.embeddableDescriptorMap.put( embeddable.getJavaType(), embeddable );
throw new IllegalArgumentException( "Could not resolve entity reference " + entityName );
}
@Override
@SuppressWarnings("unchecked")
public void visitManagedTypes(Consumer<ManagedDomainType<?>> action) {
visitEntityTypes( (Consumer) action );
visitEmbeddables( (Consumer) action );
mappedSuperclassTypeMap.values().forEach( (Consumer) action );
}
@Override
public void visitEntityTypes(Consumer<EntityDomainType<?>> action) {
entityDescriptorMap.values().forEach( action );
}
@Override
public void visitRootEntityTypes(Consumer<EntityDomainType<?>> action) {
entityDescriptorMap.values().forEach(
entityDomainType -> {
if ( entityDomainType.getSuperType() == null ) {
action.accept( entityDomainType );
}
}
);
}
@Override
public void visitEmbeddables(Consumer<EmbeddableDomainType<?>> action) {
embeddableDescriptorMap.values().forEach( action );
}
@Override
public <X> ManagedDomainType<X> managedType(Class<X> cls) {
ManagedType<?> type = entityDescriptorMap.get( cls );
if ( type == null ) {
type = mappedSuperclassTypeMap.get( cls );
}
if ( type == null ) {
type = embeddableDescriptorMap.get( cls );
}
if ( type == null ) {
// per JPA
throw new IllegalArgumentException( "Not a managed type: " + cls );
}
//noinspection unchecked
return (ManagedDomainType<X>) type;
}
@Override
public <X> EntityDomainType<X> entity(Class<X> cls) {
final EntityType<?> entityType = entityDescriptorMap.get( cls );
if ( entityType == null ) {
throw new IllegalArgumentException( "Not an entity: " + cls );
}
//noinspection unchecked
return (EntityDomainType<X>) entityType;
}
@Override
public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
final EmbeddableDomainType<?> embeddableType = embeddableDescriptorMap.get( cls );
if ( embeddableType == null ) {
throw new IllegalArgumentException( "Not an embeddable: " + cls );
}
//noinspection unchecked
return (EmbeddableDomainType<X>) embeddableType;
}
@Override
public Set<ManagedType<?>> getManagedTypes() {
final int setSize = CollectionHelper.determineProperSizing(
entityDescriptorMap.size() + mappedSuperclassTypeMap.size() + embeddableDescriptorMap.size()
);
final Set<ManagedType<?>> managedTypes = new HashSet<>( setSize );
managedTypes.addAll( entityDescriptorMap.values() );
managedTypes.addAll( mappedSuperclassTypeMap.values() );
managedTypes.addAll( embeddableDescriptorMap.values() );
return managedTypes;
}
@Override
public Set<EntityType<?>> getEntities() {
return new HashSet<>( entityDescriptorMap.values() );
}
@Override
public Set<EmbeddableType<?>> getEmbeddables() {
return new HashSet<>( embeddableDescriptorMap.values() );
}
@Override
public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> entityGraph) {
final EntityGraph old = entityGraphMap.put(
graphName,
entityGraph.makeImmutableCopy( graphName )
);
if ( old != null ) {
log.debugf( "EntityGraph being replaced on EntityManagerFactory for name %s", graphName );
}
}
@Override
public <T> RootGraphImplementor<T> findEntityGraphByName(String name) {
//noinspection unchecked
return entityGraphMap.get( name );
}
@Override
public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
final EntityDomainType<T> entityType = entity( entityClass );
if ( entityType == null ) {
throw new IllegalArgumentException( "Given class is not an entity : " + entityClass.getName() );
}
final List<RootGraphImplementor<? super T>> results = new ArrayList<>();
for ( EntityGraph entityGraph : entityGraphMap.values() ) {
if ( !( entityGraph instanceof RootGraphImplementor ) ) {
continue;
}
applyNamedEntityGraphs( mappingMetadata.getNamedEntityGraphs().values() );
final RootGraphImplementor egi = (RootGraphImplementor) entityGraph;
//noinspection unchecked
if ( egi.appliesTo( entityType ) ) {
//noinspection unchecked
results.add( egi );
}
}
return results;
}
private String resolveImportedName(String name) {
String result = nameToImportNameMap.get( name );
if ( result == null ) {
// see if the name is a fully-qualified class name
try {
getServiceRegistry().getService( ClassLoaderService.class ).classForName( name );
// it is a fully-qualified class name - add it to the cache
// so we do not keep trying later
nameToImportNameMap.put( name, name );
return name;
}
catch (ClassLoadingException cnfe) {
// it is a NOT fully-qualified class name - add a marker entry
// so we do not keep trying later
nameToImportNameMap.put( name, INVALID_IMPORT );
return null;
}
}
else {
// explicitly check for same instance
//noinspection StringEquality
if ( result == INVALID_IMPORT ) {
return null;
}
else {
return result;
}
}
}
@ -199,292 +365,6 @@ public class JpaMetamodelImpl implements JpaMetamodel {
}
}
private static void handleUnusedMappedSuperclasses(MetadataContext context) {
final Set<MappedSuperclass> unusedMappedSuperclasses = context.getUnusedMappedSuperclasses();
if ( !unusedMappedSuperclasses.isEmpty() ) {
for ( MappedSuperclass mappedSuperclass : unusedMappedSuperclasses ) {
log.unusedMappedSuperclass( mappedSuperclass.getMappedClass().getName() );
locateOrBuildMappedSuperclassType( mappedSuperclass, context );
}
}
}
private static MappedSuperclassDomainType<?> locateOrBuildMappedSuperclassType(
MappedSuperclass mappedSuperclass, MetadataContext context) {
MappedSuperclassDomainType<?> mappedSuperclassType = context.locateMappedSuperclassType( mappedSuperclass );
if ( mappedSuperclassType == null ) {
mappedSuperclassType = buildMappedSuperclassType( mappedSuperclass, context );
}
return mappedSuperclassType;
}
//TODO remove / reduce @SW scope
@SuppressWarnings("unchecked")
private static MappedSuperclassTypeImpl<?> buildMappedSuperclassType(
MappedSuperclass mappedSuperclass,
MetadataContext context) {
final MappedSuperclass superMappedSuperclass = mappedSuperclass.getSuperMappedSuperclass();
IdentifiableDomainType<?> superType = superMappedSuperclass == null
? null
: locateOrBuildMappedSuperclassType( superMappedSuperclass, context );
//no mappedSuperclass, check for a super entity
if ( superType == null ) {
final PersistentClass superPersistentClass = mappedSuperclass.getSuperPersistentClass();
superType = superPersistentClass == null
? null
: locateOrBuildEntityType( superPersistentClass, context );
}
final JavaTypeDescriptor javaTypeDescriptor = context.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( mappedSuperclass.getMappedClass() );
MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl(
javaTypeDescriptor,
mappedSuperclass,
superType,
context.getMetamodel().getJpaMetamodel()
);
context.registerMappedSuperclassType( mappedSuperclass, mappedSuperclassType );
return mappedSuperclassType;
}
private static EntityDomainType<?> locateOrBuildEntityType(
PersistentClass persistentClass,
MetadataContext context) {
EntityDomainType<?> entityType = context.locateEntityType( persistentClass );
if ( entityType == null ) {
entityType = buildEntityType( persistentClass, context );
}
return entityType;
}
//TODO remove / reduce @SW scope
@SuppressWarnings("unchecked")
private static EntityTypeImpl<?> buildEntityType(PersistentClass persistentClass, MetadataContext context) {
final Class javaType = persistentClass.getMappedClass();
context.pushEntityWorkedOn( persistentClass );
final MappedSuperclass superMappedSuperclass = persistentClass.getSuperMappedSuperclass();
IdentifiableDomainType<?> superType = superMappedSuperclass == null
? null
: locateOrBuildMappedSuperclassType( superMappedSuperclass, context );
//no mappedSuperclass, check for a super entity
if ( superType == null ) {
final PersistentClass superPersistentClass = persistentClass.getSuperclass();
superType = superPersistentClass == null
? null
: locateOrBuildEntityType( superPersistentClass, context );
}
final JavaTypeDescriptor javaTypeDescriptor = context.getTypeConfiguration()
.getJavaTypeDescriptorRegistry()
.getDescriptor( javaType );
EntityTypeImpl entityType = new EntityTypeImpl(
javaTypeDescriptor,
superType,
persistentClass,
context.getMetamodel().getJpaMetamodel()
);
context.registerEntityType( persistentClass, entityType );
context.popEntityWorkedOn( persistentClass );
return entityType;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return typeConfiguration;
}
@Override
public <X> EntityDomainType<X> entity(String entityName) {
//noinspection unchecked
return (EntityDomainType) entityDescriptorMap.get( entityName );
}
@Override
public <X> EntityDomainType<X> resolveHqlEntityReference(String entityName) {
final String rename = resolveImportedName( entityName );
if ( rename != null ) {
entityName = rename;
}
final EntityDomainType<X> entityDescriptor = entity( entityName );
if ( entityDescriptor != null ) {
return entityDescriptor;
}
final Class<X> requestedClass = resolveRequestedClass( entityName );
if ( requestedClass != null ) {
return resolveEntityReference( requestedClass );
}
throw new IllegalArgumentException( "Could not resolve entity reference " + entityName );
}
@Override
@SuppressWarnings("unchecked")
public void visitManagedTypes(Consumer<ManagedDomainType<?>> action) {
visitEntityTypes( (Consumer) action );
visitEmbeddables( (Consumer) action );
mappedSuperclassTypeMap.values().forEach( (Consumer) action );
}
@Override
public void visitEntityTypes(Consumer<EntityDomainType<?>> action) {
entityDescriptorMap.values().forEach( action );
}
@Override
public void visitRootEntityTypes(Consumer<EntityDomainType<?>> action) {
entityDescriptorMap.values().forEach(
entityDomainType -> {
if ( entityDomainType.getSuperType() == null ) {
action.accept( entityDomainType );
}
}
);
}
@Override
public void visitEmbeddables(Consumer<EmbeddableDomainType<?>> action) {
embeddableDescriptorMap.values().forEach( action );
}
@Override
public <X> ManagedDomainType<X> managedType(Class<X> cls) {
ManagedType<?> type = strictEntityDescriptorMap.get( cls );
if ( type == null ) {
type = mappedSuperclassTypeMap.get( cls );
}
if ( type == null ) {
type = embeddableDescriptorMap.get( cls );
}
if ( type == null ) {
// per JPA
throw new IllegalArgumentException( "Not a managed type: " + cls );
}
//noinspection unchecked
return (ManagedDomainType<X>) type;
}
@Override
public <X> EntityDomainType<X> entity(Class<X> cls) {
final EntityType<?> entityType = strictEntityDescriptorMap.get( cls );
if ( entityType == null ) {
throw new IllegalArgumentException( "Not an entity: " + cls );
}
//noinspection unchecked
return (EntityDomainType<X>) entityType;
}
@Override
public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
final EmbeddableDomainType<?> embeddableType = embeddableDescriptorMap.get( cls );
if ( embeddableType == null ) {
throw new IllegalArgumentException( "Not an embeddable: " + cls );
}
//noinspection unchecked
return (EmbeddableDomainType<X>) embeddableType;
}
@Override
public Set<ManagedType<?>> getManagedTypes() {
final int setSize = CollectionHelper.determineProperSizing(
entityDescriptorMap.size() + mappedSuperclassTypeMap.size() + embeddableDescriptorMap.size()
);
final Set<ManagedType<?>> managedTypes = new HashSet<>( setSize );
managedTypes.addAll( entityDescriptorMap.values() );
managedTypes.addAll( mappedSuperclassTypeMap.values() );
managedTypes.addAll( embeddableDescriptorMap.values() );
return managedTypes;
}
@Override
public Set<EntityType<?>> getEntities() {
return new HashSet<>( entityDescriptorMap.values() );
}
@Override
public Set<EmbeddableType<?>> getEmbeddables() {
return new HashSet<>( embeddableDescriptorMap.values() );
}
@Override
public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> entityGraph) {
final EntityGraph old = entityGraphMap.put(
graphName,
entityGraph.makeImmutableCopy( graphName )
);
if ( old != null ) {
log.debugf( "EntityGraph being replaced on EntityManagerFactory for name %s", graphName );
}
}
@Override
public <T> RootGraphImplementor<T> findEntityGraphByName(String name) {
//noinspection unchecked
return entityGraphMap.get( name );
}
@Override
public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Class<T> entityClass) {
final EntityDomainType<T> entityType = entity( entityClass );
if ( entityType == null ) {
throw new IllegalArgumentException( "Given class is not an entity : " + entityClass.getName() );
}
final List<RootGraphImplementor<? super T>> results = new ArrayList<>();
for ( EntityGraph entityGraph : entityGraphMap.values() ) {
if ( !(entityGraph instanceof RootGraphImplementor) ) {
continue;
}
final RootGraphImplementor egi = (RootGraphImplementor) entityGraph;
//noinspection unchecked
if ( egi.appliesTo( entityType ) ) {
//noinspection unchecked
results.add( egi );
}
}
return results;
}
private String resolveImportedName(String name) {
String result = nameToImportNameMap.get( name );
if ( result == null ) {
// see if the name is a fully-qualified class name
try {
getServiceRegistry().getService( ClassLoaderService.class ).classForName( name );
// it is a fully-qualified class name - add it to the cache
// so we do not keep trying later
nameToImportNameMap.put( name, name );
return name;
}
catch (ClassLoadingException cnfe) {
// it is a NOT fully-qualified class name - add a marker entry
// so we do not keep trying later
nameToImportNameMap.put( name, INVALID_IMPORT );
return null;
}
}
else {
// explicitly check for same instance
//noinspection StringEquality
if ( result == INVALID_IMPORT ) {
return null;
}
else {
return result;
}
}
}
private <X> Class<X> resolveRequestedClass(String entityName) {
try {
return getServiceRegistry().getService( ClassLoaderService.class ).classForName( entityName );
@ -498,7 +378,7 @@ public class JpaMetamodelImpl implements JpaMetamodel {
public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
// try the incoming Java type as a "strict" entity reference
{
final EntityDomainType<?> descriptor = strictEntityDescriptorMap.get( javaType );
final EntityDomainType<?> descriptor = entityDescriptorMap.get( javaType );
if ( descriptor != null ) {
return (EntityDomainType<T>) descriptor;
}

View File

@ -11,7 +11,6 @@ import org.hibernate.graph.spi.SubGraphImplementor;
import org.hibernate.mapping.MappedSuperclass;
import org.hibernate.metamodel.model.domain.AbstractIdentifiableType;
import org.hibernate.metamodel.model.domain.IdentifiableDomainType;
import org.hibernate.metamodel.model.domain.JpaMetamodel;
import org.hibernate.metamodel.model.domain.MappedSuperclassDomainType;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
@ -23,16 +22,14 @@ public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X> imp
public MappedSuperclassTypeImpl(
JavaTypeDescriptor<X> javaTypeDescriptor,
MappedSuperclass mappedSuperclass,
IdentifiableDomainType<? super X> superType,
JpaMetamodel jpaMetamodel) {
IdentifiableDomainType<? super X> superType) {
super(
javaTypeDescriptor.getJavaType().getName(),
javaTypeDescriptor,
superType,
mappedSuperclass.getDeclaredIdentifierMapper() != null || ( superType != null && superType.hasIdClass() ),
mappedSuperclass.hasIdentifierProperty(),
mappedSuperclass.isVersioned(),
jpaMetamodel
mappedSuperclass.isVersioned()
);
}

View File

@ -23,7 +23,7 @@ public interface AssociationType extends Type {
/**
* Get the foreign key directionality of this association
*/
public ForeignKeyDirection getForeignKeyDirection();
ForeignKeyDirection getForeignKeyDirection();
//TODO: move these to a new JoinableType abstract class,
//extended by EntityType and PersistentCollectionType:
@ -32,47 +32,47 @@ public interface AssociationType extends Type {
* Is the primary key of the owning entity table
* to be used in the join?
*/
public boolean useLHSPrimaryKey();
boolean useLHSPrimaryKey();
/**
* Get the name of a property in the owning entity
* that provides the join key (null if the identifier)
*/
public String getLHSPropertyName();
String getLHSPropertyName();
/**
* The name of a unique property of the associated entity
* that provides the join key (null if the identifier of
* an entity, or key of a collection)
*/
public String getRHSUniqueKeyPropertyName();
String getRHSUniqueKeyPropertyName();
/**
* Get the "persister" for this association - a class or
* collection persister
*/
public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException;
Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException;
/**
* Get the entity name of the associated entity
*/
public String getAssociatedEntityName(SessionFactoryImplementor factory) throws MappingException;
String getAssociatedEntityName(SessionFactoryImplementor factory) throws MappingException;
/**
* Get the "filtering" SQL fragment that is applied in the
* SQL on clause, in addition to the usual join condition
*/
public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
throws MappingException;
/**
* Get the "filtering" SQL fragment that is applied in the
* SQL on clause, in addition to the usual join condition
*/
public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters, Set<String> treatAsDeclarations);
String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters, Set<String> treatAsDeclarations);
/**
* Do we dirty check this association, even when there are
* no columns to be updated?
*/
public abstract boolean isAlwaysDirtyChecked();
boolean isAlwaysDirtyChecked();
}

View File

@ -184,7 +184,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
scope.setSessionFactory( sessionFactory );
sessionFactory.addObserver( this );
return new DomainMetamodelImpl( sessionFactory, this );
return new DomainMetamodelImpl( sessionFactory, this, this.jpaMetamodel );
}
/**

View File

@ -94,7 +94,9 @@ public class MetadataTest extends BaseEntityManagerFunctionalTestCase {
.addAnnotatedClass( WithGenericCollection.class )
.buildMetadata();
SessionFactoryImplementor sfi = (SessionFactoryImplementor) metadata.buildSessionFactory();
DomainMetamodelImpl metamodel = new DomainMetamodelImpl( sfi, ( (MetadataImplementor) metadata ).getTypeConfiguration() );
DomainMetamodelImpl metamodel = new DomainMetamodelImpl( sfi, ( (MetadataImplementor) metadata ).getTypeConfiguration(),
this.jpaMetamodel
);
metamodel.initialize( (MetadataImplementor) metadata, JpaMetaModelPopulationSetting.IGNORE_UNSUPPORTED );
sfi.close();
}