1010import java .io .Serializable ;
1111import java .lang .reflect .Field ;
1212import java .util .ArrayList ;
13+ import java .util .Arrays ;
1314import java .util .Collection ;
1415import java .util .Collections ;
1516import java .util .HashMap ;
2223import java .util .stream .Collectors ;
2324
2425import org .checkerframework .checker .nullness .qual .Nullable ;
26+
2527import org .hibernate .boot .model .NamedEntityGraphDefinition ;
2628import org .hibernate .boot .registry .classloading .spi .ClassLoaderService ;
2729import org .hibernate .boot .registry .classloading .spi .ClassLoadingException ;
7173import jakarta .persistence .metamodel .Type ;
7274
7375/**
74- *
7576 * @author Steve Ebersole
7677 */
7778public class JpaMetamodelImpl implements JpaMetamodelImplementor , Serializable {
@@ -104,7 +105,7 @@ private static class ImportInfo<T> {
104105 private final Map <Class <?>, String > entityProxyInterfaceMap = new HashMap <>();
105106
106107 private final Map <String , ImportInfo <?>> nameToImportMap = new ConcurrentHashMap <>();
107- private final Map <String ,Object > knownInvalidnameToImportMap = new ConcurrentHashMap <>();
108+ private final Map <String , Object > knownInvalidnameToImportMap = new ConcurrentHashMap <>();
108109
109110
110111 public JpaMetamodelImpl (
@@ -284,7 +285,7 @@ public Set<EmbeddableType<?>> getEmbeddables() {
284285
285286 @ Override
286287 public @ Nullable Set <String > getEnumTypesForValue (String enumValue ) {
287- return allowedEnumLiteralsToEnumTypeNames .get ( enumValue );
288+ return allowedEnumLiteralsToEnumTypeNames .get ( enumValue );
288289 }
289290
290291 @ Override
@@ -362,8 +363,7 @@ public <T> List<RootGraphImplementor<? super T>> findEntityGraphsByJavaType(Clas
362363 final List <RootGraphImplementor <? super T >> results = new ArrayList <>();
363364 for ( RootGraphImplementor <?> entityGraph : entityGraphMap .values () ) {
364365 if ( entityGraph .appliesTo ( entityType ) ) {
365- @ SuppressWarnings ("unchecked" )
366- final RootGraphImplementor <? super T > result = (RootGraphImplementor <? super T >) entityGraph ;
366+ @ SuppressWarnings ("unchecked" ) final RootGraphImplementor <? super T > result = (RootGraphImplementor <? super T >) entityGraph ;
367367 results .add ( result );
368368 }
369369 }
@@ -437,22 +437,59 @@ private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> named
437437 );
438438 }
439439
440- final RootGraphImpl <Object > entityGraph = new RootGraphImpl <>( definition .getRegisteredName (), entityType );
441-
442440 final NamedEntityGraph namedEntityGraph = definition .getAnnotation ();
441+ final RootGraphImpl <?> entityGraph =
442+ createEntityGraph (
443+ namedEntityGraph ,
444+ definition .getRegisteredName (),
445+ entityType ,
446+ namedEntityGraph .includeAllAttributes ()
447+ );
443448
444- if ( namedEntityGraph .includeAllAttributes () ) {
445- for ( Attribute <? super Object , ?> attribute : entityType .getAttributes () ) {
446- entityGraph .addAttributeNodes ( attribute );
447- }
448- }
449+ entityGraphMap .put ( definition .getRegisteredName (), entityGraph );
450+ }
451+ }
449452
450- if ( namedEntityGraph .attributeNodes () != null ) {
451- applyNamedAttributeNodes ( namedEntityGraph .attributeNodes (), namedEntityGraph , entityGraph );
452- }
453+ private <T > RootGraphImpl <T > createEntityGraph (
454+ NamedEntityGraph namedEntityGraph ,
455+ String registeredName ,
456+ EntityDomainType <T > entityType ,
457+ boolean includeAllAttributes ) {
458+ final RootGraphImpl <T > entityGraph =
459+ createRootGraph ( registeredName , entityType , includeAllAttributes );
453460
454- entityGraphMap .put ( definition .getRegisteredName (), entityGraph );
461+ if ( namedEntityGraph .subclassSubgraphs () != null ) {
462+ Arrays
463+ .stream ( namedEntityGraph .subclassSubgraphs () )
464+ .forEach ( subclassSubgraph -> {
465+ var subgraph = entityGraph .addTreatedSubgraph ( subclassSubgraph .type () );
466+ applyNamedAttributeNodes (
467+ subclassSubgraph .attributeNodes (),
468+ namedEntityGraph ,
469+ subgraph
470+ );
471+
472+ } );
473+ }
474+
475+ if ( namedEntityGraph .attributeNodes () != null ) {
476+ applyNamedAttributeNodes ( namedEntityGraph .attributeNodes (), namedEntityGraph , entityGraph );
477+ }
478+
479+
480+ return entityGraph ;
481+ }
482+
483+ @ SuppressWarnings ("unchecked" )
484+ private static <T > RootGraphImpl <T > createRootGraph (
485+ String name , EntityDomainType <T > entityType , boolean includeAllAttributes ) {
486+ final RootGraphImpl <T > entityGraph = new RootGraphImpl <>( name , entityType );
487+ if ( includeAllAttributes ) {
488+ for ( Attribute <? super T , ?> attribute : entityType .getAttributes () ) {
489+ entityGraph .addAttributeNodes ( (Attribute <T , ?>) attribute );
490+ }
455491 }
492+ return entityGraph ;
456493 }
457494
458495 private void applyNamedAttributeNodes (
@@ -463,31 +500,33 @@ private void applyNamedAttributeNodes(
463500 final String value = namedAttributeNode .value ();
464501 AttributeNodeImplementor <?> attributeNode = graphNode .addAttributeNode ( value );
465502 if ( StringHelper .isNotEmpty ( namedAttributeNode .subgraph () ) ) {
466- final SubGraphImplementor <?> subgraph = attributeNode .makeSubGraph ();
467503 applyNamedSubgraphs (
468504 namedEntityGraph ,
469505 namedAttributeNode .subgraph (),
470- subgraph
506+ attributeNode
471507 );
472508 }
473509 if ( StringHelper .isNotEmpty ( namedAttributeNode .keySubgraph () ) ) {
474- final SubGraphImplementor <?> subgraph = attributeNode .makeKeySubGraph ();
475-
476510 applyNamedSubgraphs (
477511 namedEntityGraph ,
478512 namedAttributeNode .keySubgraph (),
479- subgraph
513+ attributeNode
480514 );
481515 }
482516 }
483517 }
484518
485- private void applyNamedSubgraphs (
519+ @ SuppressWarnings ("unchecked" )
520+ private <T > void applyNamedSubgraphs (
486521 NamedEntityGraph namedEntityGraph ,
487522 String subgraphName ,
488- SubGraphImplementor <?> subgraph ) {
523+ AttributeNodeImplementor < T > attributeNode ) {
489524 for ( NamedSubgraph namedSubgraph : namedEntityGraph .subgraphs () ) {
490525 if ( subgraphName .equals ( namedSubgraph .name () ) ) {
526+ var isDefaultSubgraphType = namedSubgraph .type ().equals ( void .class );
527+ SubGraphImplementor <?> subgraph = attributeNode
528+ .makeSubGraph ( isDefaultSubgraphType ? null : namedSubgraph .type () );
529+
491530 applyNamedAttributeNodes (
492531 namedSubgraph .attributeNodes (),
493532 namedEntityGraph ,
@@ -581,7 +620,10 @@ public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
581620 }
582621 }
583622
584- throw new EntityTypeException ( "Could not resolve entity class '" + javaType .getName () + "'" , javaType .getName () );
623+ throw new EntityTypeException (
624+ "Could not resolve entity class '" + javaType .getName () + "'" ,
625+ javaType .getName ()
626+ );
585627 }
586628
587629 @ Override
@@ -597,7 +639,7 @@ public void processJpa(
597639 JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting ,
598640 Collection <NamedEntityGraphDefinition > namedEntityGraphDefinitions ,
599641 RuntimeModelCreationContext runtimeModelCreationContext ) {
600- bootMetamodel .getImports ().forEach ( ( k , v ) -> this .nameToImportMap .put ( k , new ImportInfo <>( v , null ) ) );
642+ bootMetamodel .getImports ().forEach ( (k , v ) -> this .nameToImportMap .put ( k , new ImportInfo <>( v , null ) ) );
601643 this .entityProxyInterfaceMap .putAll ( entityProxyInterfaceMap );
602644
603645 final MetadataContext context = new MetadataContext (
0 commit comments