55package org .hibernate .metamodel .model .domain .internal ;
66
77import java .io .Serializable ;
8- import java .util .ArrayList ;
98import java .util .Arrays ;
109import java .util .HashSet ;
1110import java .util .List ;
2019import org .checkerframework .checker .nullness .qual .Nullable ;
2120import org .hibernate .EntityNameResolver ;
2221import org .hibernate .HibernateException ;
23- import org .hibernate .MappingException ;
2422import org .hibernate .UnknownEntityTypeException ;
2523import org .hibernate .boot .spi .MetadataImplementor ;
2624import org .hibernate .cache .spi .CacheImplementor ;
27- import org .hibernate .cache .spi .access .CollectionDataAccess ;
28- import org .hibernate .cache .spi .access .EntityDataAccess ;
29- import org .hibernate .cache .spi .access .NaturalIdDataAccess ;
3025import org .hibernate .graph .RootGraph ;
3126import org .hibernate .graph .spi .RootGraphImplementor ;
3227import org .hibernate .internal .CoreLogging ;
4035import org .hibernate .mapping .PersistentClass ;
4136import org .hibernate .metamodel .MappingMetamodel ;
4237import org .hibernate .metamodel .mapping .EmbeddableValuedModelPart ;
43- import org .hibernate .metamodel .mapping .EntityMappingType ;
4438import org .hibernate .metamodel .mapping .MappingModelExpressible ;
4539import org .hibernate .metamodel .mapping .internal .MappingModelCreationProcess ;
4640import org .hibernate .metamodel .model .domain .BasicDomainType ;
8175import jakarta .persistence .metamodel .ManagedType ;
8276import jakarta .persistence .metamodel .Metamodel ;
8377
84- import static org .hibernate .internal .util .collections .ArrayHelper .EMPTY_STRING_ARRAY ;
8578import static org .hibernate .metamodel .internal .JpaMetamodelPopulationSetting .determineJpaMetaModelPopulationSetting ;
8679import static org .hibernate .metamodel .internal .JpaStaticMetamodelPopulationSetting .determineJpaStaticMetaModelPopulationSetting ;
8780
9790 */
9891public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
9992 implements MappingMetamodelImplementor ,JpaMetamodel , Metamodel , Serializable {
100- // todo : Integrate EntityManagerLogger into CoreMessageLogger
101- private static final CoreMessageLogger log = CoreLogging .messageLogger ( MappingMetamodelImpl .class );
10293
103- //NOTE: we suppress deprecation warnings because at the moment we
104- //implement a deprecated API so have to override deprecated things
94+ private static final CoreMessageLogger log = CoreLogging .messageLogger ( MappingMetamodelImpl .class );
10595
10696 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10797 // JpaMetamodel
@@ -110,7 +100,6 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
110100
111101 private final Map <Class <?>, String > entityProxyInterfaceMap = new ConcurrentHashMap <>();
112102
113-
114103 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115104 // RuntimeModel
116105
@@ -119,28 +108,29 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
119108 private final Map <String , Set <String >> collectionRolesByEntityParticipant = new ConcurrentHashMap <>();
120109
121110 private final Map <NavigableRole , EmbeddableValuedModelPart > embeddableValuedModelPart = new ConcurrentHashMap <>();
111+
122112 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123113 // DomainMetamodel
124114
125115 private final Set <EntityNameResolver > entityNameResolvers = new HashSet <>();
126116
127117
128118 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129- // NOTE : Relational/mapping information is not part of the JPA metamodel
130- // (type system). However, this relational/mapping info *is* part of the
131- // Hibernate metamodel. This is a mismatch. Normally this is not a
132- // problem - ignoring Hibernate's representation mode (entity mode),
133- // an entity (or mapped superclass) *Class* always refers to the same
134- // EntityType ( JPA) and EntityPersister ( Hibernate).. The problem is
135- // in regards to embeddables. For an embeddable, as with the rest of its
136- // metamodel, Hibernate combines the embeddable's relational/mapping
137- // while JPA does not. This is consistent with each's model paradigm.
138- // However, it causes a mismatch in that while JPA expects a single
139- // "type descriptor" for a given embeddable class, Hibernate incorporates
140- // the relational/mapping info so we have a "type descriptor" for each
141- // usage of that embeddable. Think embeddable versus embedded.
119+ // NOTE: Relational/mapping information is not part of the JPA metamodel
120+ // (type system). However, this relational/mapping info *is* part of the
121+ // Hibernate metamodel. This is a mismatch. Normally this is not a problem
122+ // - ignoring Hibernate's representation mode (entity mode), the Class
123+ // object for an entity (or mapped superclass) always refers to the same
124+ // JPA EntityType and Hibernate EntityPersister. The problem arises with
125+ // embeddables. For an embeddable, as with the rest of its metamodel,
126+ // Hibernate combines the embeddable's relational/mapping while JPA does
127+ // not. This is perfectly consistent with each paradigm. But it results
128+ // in a mismatch since JPA expects a single "type descriptor" for a
129+ // given embeddable class while Hibernate incorporates the
130+ // relational/mapping info so we have a "type descriptor" for each usage
131+ // of that embeddable type. ( Think embeddable versus embedded.)
142132 //
143- // To account for this, we track both paradigms here...
133+ // To account for this, we track both paradigms here.
144134
145135 // There can be multiple instances of an Embeddable type, each one being relative to its parent entity.
146136
@@ -225,54 +215,50 @@ private void processBootEntities(
225215 RuntimeModelCreationContext modelCreationContext ) {
226216 for ( final PersistentClass model : entityBindings ) {
227217 final NavigableRole rootEntityRole = new NavigableRole ( model .getRootClass ().getEntityName () );
228- final EntityDataAccess accessStrategy = cacheImplementor .getEntityRegionAccess ( rootEntityRole );
229- final NaturalIdDataAccess naturalIdAccessStrategy = cacheImplementor
230- .getNaturalIdCacheRegionAccessStrategy ( rootEntityRole );
231-
232- final EntityPersister cp = persisterFactory .createEntityPersister (
233- model ,
234- accessStrategy ,
235- naturalIdAccessStrategy ,
236- modelCreationContext
237- );
238- entityPersisterMap .put ( model .getEntityName (), cp );
218+ final EntityPersister entityPersister =
219+ persisterFactory .createEntityPersister (
220+ model ,
221+ cacheImplementor .getEntityRegionAccess ( rootEntityRole ),
222+ cacheImplementor .getNaturalIdCacheRegionAccessStrategy ( rootEntityRole ),
223+ modelCreationContext
224+ );
225+ entityPersisterMap .put ( model .getEntityName (), entityPersister );
239226 // Also register the persister under the class name if available,
240227 // otherwise the getEntityDescriptor(Class) won't work for entities with custom entity names
241228 if ( model .getClassName () != null && !model .getClassName ().equals ( model .getEntityName () ) ) {
242229 // But only if the class name is not registered already,
243230 // as we can have the same class mapped to multiple entity names
244- entityPersisterMap .putIfAbsent ( model .getClassName (), cp );
231+ entityPersisterMap .putIfAbsent ( model .getClassName (), entityPersister );
245232 }
246233
247- if ( cp .getConcreteProxyClass () != null
248- && cp .getConcreteProxyClass ().isInterface ()
249- && !Map .class .isAssignableFrom ( cp .getConcreteProxyClass () )
250- && cp .getMappedClass () != cp .getConcreteProxyClass () ) {
234+ if ( entityPersister .getConcreteProxyClass () != null
235+ && entityPersister .getConcreteProxyClass ().isInterface ()
236+ && !Map .class .isAssignableFrom ( entityPersister .getConcreteProxyClass () )
237+ && entityPersister .getMappedClass () != entityPersister .getConcreteProxyClass () ) {
251238 // IMPL NOTE : we exclude Map based proxy interfaces here because that should
252239 // indicate MAP entity mode.0
253240
254- if ( cp .getMappedClass ().equals ( cp .getConcreteProxyClass () ) ) {
255- // this part handles an odd case in the Hibernate test suite where we map an interface
256- // as the class and the proxy. I cannot think of a real life use case for that
257- // specific test, but..
241+ if ( entityPersister .getMappedClass ().equals ( entityPersister .getConcreteProxyClass () ) ) {
242+ // This part handles an odd case in the Hibernate test suite where we map an interface
243+ // as the class and the proxy. I cannot think of a real-life use case for this.
258244 if ( log .isDebugEnabled () ) {
259245 log .debugf (
260246 "Entity [%s] mapped same interface [%s] as class and proxy" ,
261- cp .getEntityName (),
262- cp .getMappedClass ()
247+ entityPersister .getEntityName (),
248+ entityPersister .getMappedClass ()
263249 );
264250 }
265251 }
266252 else {
267- final String old = entityProxyInterfaceMap .put ( cp .getConcreteProxyClass (), cp .getEntityName () );
253+ final String old = entityProxyInterfaceMap .put ( entityPersister .getConcreteProxyClass (), entityPersister .getEntityName () );
268254 if ( old != null ) {
269255 throw new HibernateException (
270256 String .format (
271257 Locale .ENGLISH ,
272258 "Multiple entities [%s, %s] named the same interface [%s] as their proxy which is not supported" ,
273259 old ,
274- cp .getEntityName (),
275- cp .getConcreteProxyClass ().getName ()
260+ entityPersister .getEntityName (),
261+ entityPersister .getConcreteProxyClass ().getName ()
276262 )
277263 );
278264 }
@@ -288,15 +274,12 @@ private void processBootCollections(
288274 RuntimeModelCreationContext modelCreationContext ) {
289275 for ( final Collection model : collectionBindings ) {
290276 final NavigableRole navigableRole = new NavigableRole ( model .getRole () );
291-
292- final CollectionDataAccess accessStrategy = cacheImplementor .getCollectionRegionAccess (
293- navigableRole );
294-
295- final CollectionPersister persister = persisterFactory .createCollectionPersister (
296- model ,
297- accessStrategy ,
298- modelCreationContext
299- );
277+ final CollectionPersister persister =
278+ persisterFactory .createCollectionPersister (
279+ model ,
280+ cacheImplementor .getCollectionRegionAccess ( navigableRole ),
281+ modelCreationContext
282+ );
300283 collectionPersisterMap .put ( model .getRole (), persister );
301284 if ( persister .getIndexType () instanceof org .hibernate .type .EntityType entityType ) {
302285 registerEntityParticipant ( entityType , persister );
@@ -400,7 +383,7 @@ public boolean isEntityClass(Class<?> entityJavaType) {
400383 public EntityPersister getEntityDescriptor (Class <?> entityJavaType ) {
401384 EntityPersister entityPersister = entityPersisterMap .get ( entityJavaType .getName () );
402385 if ( entityPersister == null ) {
403- String mappedEntityName = entityProxyInterfaceMap .get ( entityJavaType );
386+ final String mappedEntityName = entityProxyInterfaceMap .get ( entityJavaType );
404387 if ( mappedEntityName != null ) {
405388 entityPersister = entityPersisterMap .get ( mappedEntityName );
406389 }
@@ -417,7 +400,7 @@ public EntityPersister getEntityDescriptor(Class<?> entityJavaType) {
417400 public EntityPersister locateEntityDescriptor (Class <?> byClass ) {
418401 EntityPersister entityPersister = entityPersisterMap .get ( byClass .getName () );
419402 if ( entityPersister == null ) {
420- String mappedEntityName = entityProxyInterfaceMap .get ( byClass );
403+ final String mappedEntityName = entityProxyInterfaceMap .get ( byClass );
421404 if ( mappedEntityName != null ) {
422405 entityPersister = entityPersisterMap .get ( mappedEntityName );
423406 }
@@ -655,35 +638,6 @@ public List<RootGraph<?>> findRootGraphsForType(EntityPersister baseEntityDescri
655638 return null ;
656639 }
657640
658- private String [] doGetImplementors (Class <?> clazz ) throws MappingException {
659- final ArrayList <String > results = new ArrayList <>();
660- forEachEntityDescriptor ( descriptor -> {
661- final String checkQueryableEntityName = ((EntityMappingType ) descriptor ).getEntityName ();
662- final boolean isMappedClass = clazz .getName ().equals ( checkQueryableEntityName );
663- if ( isMappedClass ) {
664- results .add ( checkQueryableEntityName );
665- }
666- else {
667- final Class <?> mappedClass = descriptor .getMappedClass ();
668- if ( mappedClass != null && clazz .isAssignableFrom ( mappedClass ) ) {
669- final boolean assignableSuperclass ;
670- if ( descriptor .isInherited () ) {
671- final String superTypeName = descriptor .getSuperMappingType ().getEntityName ();
672- final Class <?> mappedSuperclass = getEntityDescriptor ( superTypeName ).getMappedClass ();
673- assignableSuperclass = clazz .isAssignableFrom ( mappedSuperclass );
674- }
675- else {
676- assignableSuperclass = false ;
677- }
678- if ( !assignableSuperclass ) {
679- results .add ( checkQueryableEntityName );
680- }
681- }
682- }
683- } );
684- return results .toArray ( EMPTY_STRING_ARRAY );
685- }
686-
687641 @ Override
688642 public MappingModelExpressible <?> resolveMappingExpressible (
689643 SqmExpressible <?> sqmExpressible ,
0 commit comments