6 - SQM based on JPA type system, RuntimeModelCreationProcess
This commit is contained in:
parent
f52e305ffb
commit
f20d36be40
|
@ -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 ) {
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue