20
20
import java .util .stream .Collectors ;
21
21
22
22
import org .checkerframework .checker .nullness .qual .Nullable ;
23
+
23
24
import org .hibernate .boot .model .NamedEntityGraphDefinition ;
24
25
import org .hibernate .boot .query .NamedQueryDefinition ;
25
26
import org .hibernate .boot .registry .classloading .spi .ClassLoaderService ;
73
74
import static org .hibernate .metamodel .internal .InjectionHelper .injectTypedQueryReference ;
74
75
75
76
/**
76
- *
77
77
* @author Steve Ebersole
78
78
*/
79
79
public class JpaMetamodelImpl implements JpaMetamodelImplementor , Serializable {
@@ -106,7 +106,7 @@ private ImportInfo(String importedName, Class<T> loadedClass) {
106
106
private final Map <Class <?>, String > entityProxyInterfaceMap = new HashMap <>();
107
107
108
108
private final Map <String , ImportInfo <?>> nameToImportMap = new ConcurrentHashMap <>();
109
- private final Map <String ,Object > knownInvalidnameToImportMap = new ConcurrentHashMap <>();
109
+ private final Map <String , Object > knownInvalidnameToImportMap = new ConcurrentHashMap <>();
110
110
111
111
112
112
public JpaMetamodelImpl (
@@ -143,13 +143,14 @@ public JpaCompliance getJpaCompliance() {
143
143
public <X > ManagedDomainType <X > managedType (String typeName ) {
144
144
final ManagedDomainType <X > managedType = findManagedType ( typeName );
145
145
if ( managedType == null ) {
146
- throw new IllegalArgumentException ("Not a managed type: " + typeName );
146
+ throw new IllegalArgumentException ( "Not a managed type: " + typeName );
147
147
}
148
148
return managedType ;
149
149
}
150
150
151
151
@ Override
152
- @ Nullable public EntityDomainType <?> findEntityType (@ Nullable String entityName ) {
152
+ @ Nullable
153
+ public EntityDomainType <?> findEntityType (@ Nullable String entityName ) {
153
154
if ( entityName == null ) {
154
155
return null ;
155
156
}
@@ -162,18 +163,19 @@ public EntityDomainType<?> entity(String entityName) {
162
163
final EntityDomainType <?> entityType = findEntityType ( entityName );
163
164
if ( entityType == null ) {
164
165
// per JPA
165
- throw new IllegalArgumentException ("Not an entity: " + entityName );
166
+ throw new IllegalArgumentException ( "Not an entity: " + entityName );
166
167
}
167
168
return entityType ;
168
169
}
169
170
170
171
@ Override
171
- @ Nullable public EmbeddableDomainType <?> findEmbeddableType (@ Nullable String embeddableName ) {
172
+ @ Nullable
173
+ public EmbeddableDomainType <?> findEmbeddableType (@ Nullable String embeddableName ) {
172
174
if ( embeddableName == null ) {
173
175
return null ;
174
176
}
175
177
final ManagedDomainType <?> managedType = managedTypeByName .get ( embeddableName );
176
- if ( !( managedType instanceof EmbeddableDomainType <?> embeddableDomainType ) ) {
178
+ if ( !( managedType instanceof EmbeddableDomainType <?> embeddableDomainType ) ) {
177
179
return null ;
178
180
}
179
181
return embeddableDomainType ;
@@ -183,7 +185,7 @@ public EntityDomainType<?> entity(String entityName) {
183
185
public EmbeddableDomainType <?> embeddable (String embeddableName ) {
184
186
final EmbeddableDomainType <?> embeddableType = findEmbeddableType ( embeddableName );
185
187
if ( embeddableType == null ) {
186
- throw new IllegalArgumentException ("Not an embeddable: " + embeddableName );
188
+ throw new IllegalArgumentException ( "Not an embeddable: " + embeddableName );
187
189
}
188
190
return embeddableType ;
189
191
}
@@ -226,7 +228,8 @@ public <X> EntityDomainType<X> resolveHqlEntityReference(String entityName) {
226
228
}
227
229
228
230
@ Override
229
- @ Nullable public <X > ManagedDomainType <X > findManagedType (Class <X > cls ) {
231
+ @ Nullable
232
+ public <X > ManagedDomainType <X > findManagedType (Class <X > cls ) {
230
233
//noinspection unchecked
231
234
return (ManagedDomainType <X >) managedTypeByClass .get ( cls );
232
235
}
@@ -242,7 +245,8 @@ public <X> ManagedDomainType<X> managedType(Class<X> cls) {
242
245
}
243
246
244
247
@ Override
245
- @ Nullable public <X > EntityDomainType <X > findEntityType (Class <X > cls ) {
248
+ @ Nullable
249
+ public <X > EntityDomainType <X > findEntityType (Class <X > cls ) {
246
250
final ManagedType <?> type = managedTypeByClass .get ( cls );
247
251
if ( !( type instanceof EntityDomainType <?> ) ) {
248
252
return null ;
@@ -281,7 +285,7 @@ public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
281
285
282
286
private Collection <ManagedDomainType <?>> getAllManagedTypes () {
283
287
// should never happen
284
- return switch (jpaMetaModelPopulationSetting ) {
288
+ return switch ( jpaMetaModelPopulationSetting ) {
285
289
case IGNORE_UNSUPPORTED -> managedTypeByClass .values ();
286
290
case ENABLED -> managedTypeByName .values ();
287
291
case DISABLED -> emptySet ();
@@ -311,7 +315,7 @@ public Set<EmbeddableType<?>> getEmbeddables() {
311
315
312
316
@ Override
313
317
public @ Nullable Set <String > getEnumTypesForValue (String enumValue ) {
314
- return allowedEnumLiteralsToEnumTypeNames .get ( enumValue );
318
+ return allowedEnumLiteralsToEnumTypeNames .get ( enumValue );
315
319
}
316
320
317
321
@ Override
@@ -388,7 +392,8 @@ public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> en
388
392
}
389
393
}
390
394
391
- @ Override @ SuppressWarnings ("unchecked" )
395
+ @ Override
396
+ @ SuppressWarnings ("unchecked" )
392
397
public <T > RootGraphImplementor <T > findEntityGraphByName (String name ) {
393
398
return (RootGraphImplementor <T >) entityGraphMap .get ( name );
394
399
}
@@ -494,17 +499,48 @@ private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> named
494
499
495
500
);
496
501
}
502
+
497
503
final NamedEntityGraph namedEntityGraph = definition .getAnnotation ();
498
504
final RootGraphImpl <?> entityGraph =
499
- createRootGraph ( definition .getRegisteredName (), entityType ,
500
- namedEntityGraph .includeAllAttributes () );
501
- if ( namedEntityGraph .attributeNodes () != null ) {
502
- applyNamedAttributeNodes ( namedEntityGraph .attributeNodes (), namedEntityGraph , entityGraph );
503
- }
505
+ createEntityGraph (
506
+ namedEntityGraph ,
507
+ definition .getRegisteredName (),
508
+ entityType ,
509
+ namedEntityGraph .includeAllAttributes ()
510
+ );
511
+
504
512
entityGraphMap .put ( definition .getRegisteredName (), entityGraph );
505
513
}
506
514
}
507
515
516
+ private <T > RootGraphImpl <T > createEntityGraph (
517
+ NamedEntityGraph namedEntityGraph ,
518
+ String registeredName ,
519
+ EntityDomainType <T > entityType ,
520
+ boolean includeAllAttributes ) {
521
+ final RootGraphImpl <T > entityGraph =
522
+ createRootGraph ( registeredName , entityType , includeAllAttributes );
523
+
524
+ if ( namedEntityGraph .subclassSubgraphs () != null ) {
525
+ for ( var subclassSubgraph : namedEntityGraph .subclassSubgraphs () ) {
526
+ GraphImplementor <?> subgraph = (GraphImplementor <?>) entityGraph .addTreatedSubgraph (
527
+ (Class ) subclassSubgraph .type () );
528
+
529
+ applyNamedAttributeNodes (
530
+ subclassSubgraph .attributeNodes (),
531
+ namedEntityGraph ,
532
+ subgraph
533
+ );
534
+ }
535
+ }
536
+
537
+ if ( namedEntityGraph .attributeNodes () != null ) {
538
+ applyNamedAttributeNodes ( namedEntityGraph .attributeNodes (), namedEntityGraph , entityGraph );
539
+ }
540
+
541
+ return entityGraph ;
542
+ }
543
+
508
544
private static <T > RootGraphImpl <T > createRootGraph (
509
545
String name , EntityDomainType <T > entityType , boolean includeAllAttributes ) {
510
546
final RootGraphImpl <T > entityGraph = new RootGraphImpl <>( name , entityType );
@@ -521,31 +557,44 @@ private void applyNamedAttributeNodes(
521
557
NamedEntityGraph namedEntityGraph ,
522
558
GraphImplementor <?> graphNode ) {
523
559
for ( NamedAttributeNode namedAttributeNode : namedAttributeNodes ) {
524
- final AttributeNodeImplementor <?> attributeNode =
525
- graphNode .findOrCreateAttributeNode ( namedAttributeNode .value () );
560
+ final String value = namedAttributeNode .value ();
561
+ final AttributeNodeImplementor <?> attributeNode = (AttributeNodeImplementor <?>) graphNode .addAttributeNode (
562
+ value );
563
+
526
564
if ( isNotEmpty ( namedAttributeNode .subgraph () ) ) {
527
565
applyNamedSubgraphs (
528
566
namedEntityGraph ,
529
567
namedAttributeNode .subgraph (),
530
- attributeNode .makeSubGraph ()
568
+ attributeNode ,
569
+ false
531
570
);
532
571
}
533
572
if ( isNotEmpty ( namedAttributeNode .keySubgraph () ) ) {
534
573
applyNamedSubgraphs (
535
574
namedEntityGraph ,
536
575
namedAttributeNode .keySubgraph (),
537
- attributeNode .makeKeySubGraph ()
576
+ attributeNode ,
577
+ true
538
578
);
539
579
}
540
580
}
541
581
}
542
582
543
- private void applyNamedSubgraphs (
583
+ @ SuppressWarnings ({ "unchecked" , "rawtypes" })
584
+ private <T > void applyNamedSubgraphs (
544
585
NamedEntityGraph namedEntityGraph ,
545
586
String subgraphName ,
546
- SubGraphImplementor <?> subgraph ) {
587
+ AttributeNodeImplementor < T > attributeNode , Boolean isKeySubGraph ) {
547
588
for ( NamedSubgraph namedSubgraph : namedEntityGraph .subgraphs () ) {
548
589
if ( subgraphName .equals ( namedSubgraph .name () ) ) {
590
+ final var isDefaultSubgraphType = namedSubgraph .type ().equals ( void .class );
591
+ final Class subGraphType = isDefaultSubgraphType ? null : namedSubgraph .type ();
592
+
593
+ final SubGraphImplementor <?> subgraph = makeAttributeNodeSubgraph (
594
+ attributeNode , isKeySubGraph ,
595
+ subGraphType
596
+ );
597
+
549
598
applyNamedAttributeNodes (
550
599
namedSubgraph .attributeNodes (),
551
600
namedEntityGraph ,
@@ -555,6 +604,21 @@ private void applyNamedSubgraphs(
555
604
}
556
605
}
557
606
607
+ private static <T > SubGraphImplementor <?> makeAttributeNodeSubgraph (
608
+ AttributeNodeImplementor <T > attributeNode ,
609
+ Boolean isKeySubGraph ,
610
+ Class <T > subGraphType ) {
611
+
612
+ if ( isKeySubGraph ) {
613
+ return subGraphType != null ? attributeNode .makeKeySubGraph ( subGraphType )
614
+ : attributeNode .makeKeySubGraph ();
615
+ }
616
+
617
+ return subGraphType != null ?
618
+ attributeNode .makeSubGraph ( subGraphType ) :
619
+ attributeNode .makeSubGraph ();
620
+ }
621
+
558
622
private <X > Class <X > resolveRequestedClass (String entityName ) {
559
623
try {
560
624
return getServiceRegistry ().requireService ( ClassLoaderService .class )
@@ -631,7 +695,10 @@ public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
631
695
}
632
696
}
633
697
634
- throw new EntityTypeException ( "Could not resolve entity class '" + javaType .getName () + "'" , javaType .getName () );
698
+ throw new EntityTypeException (
699
+ "Could not resolve entity class '" + javaType .getName () + "'" ,
700
+ javaType .getName ()
701
+ );
635
702
}
636
703
637
704
@ Override
@@ -716,11 +783,30 @@ public void processJpa(
716
783
717
784
private void populateStaticMetamodel (MetadataImplementor bootMetamodel , MetadataContext context ) {
718
785
bootMetamodel .visitNamedHqlQueryDefinitions ( definition
719
- -> injectTypedQueryReference ( definition , namedQueryMetamodelClass ( definition , context ) ) );
786
+ -> injectTypedQueryReference (
787
+ definition ,
788
+ namedQueryMetamodelClass (
789
+ definition ,
790
+ context
791
+ )
792
+ ) );
720
793
bootMetamodel .visitNamedNativeQueryDefinitions ( definition
721
- -> injectTypedQueryReference ( definition , namedQueryMetamodelClass ( definition , context ) ) );
722
- bootMetamodel .getNamedEntityGraphs ().values ().forEach (definition
723
- -> injectEntityGraph ( definition , graphMetamodelClass ( definition , context ), this ) );
794
+ -> injectTypedQueryReference (
795
+ definition ,
796
+ namedQueryMetamodelClass (
797
+ definition ,
798
+ context
799
+ )
800
+ ) );
801
+ bootMetamodel .getNamedEntityGraphs ().values ().forEach ( definition
802
+ -> injectEntityGraph (
803
+ definition ,
804
+ graphMetamodelClass (
805
+ definition ,
806
+ context
807
+ ),
808
+ this
809
+ ) );
724
810
}
725
811
726
812
private Class <?> namedQueryMetamodelClass (NamedQueryDefinition <?> definition , MetadataContext context ) {
@@ -764,9 +850,7 @@ private <T> EntityDomainType<T> locateOrBuildEntityType(
764
850
MetadataContext context ,
765
851
final TypeConfiguration typeConfiguration ) {
766
852
@ SuppressWarnings ("unchecked" )
767
- final EntityDomainType <T > entityType =
768
- (EntityDomainType <T >)
769
- context .locateEntityType ( persistentClass );
853
+ final EntityDomainType <T > entityType = (EntityDomainType <T >) context .locateEntityType ( persistentClass );
770
854
return entityType == null
771
855
? buildEntityType ( persistentClass , context , typeConfiguration )
772
856
: entityType ;
@@ -818,8 +902,7 @@ private <T> MappedSuperclassDomainType<T> locateOrBuildMappedSuperclassType(
818
902
TypeConfiguration typeConfiguration ) {
819
903
@ SuppressWarnings ("unchecked" )
820
904
final MappedSuperclassDomainType <T > mappedSuperclassType =
821
- (MappedSuperclassDomainType <T >)
822
- context .locateMappedSuperclassType ( mappedSuperclass );
905
+ (MappedSuperclassDomainType <T >) context .locateMappedSuperclassType ( mappedSuperclass );
823
906
return mappedSuperclassType == null
824
907
? buildMappedSuperclassType ( mappedSuperclass , context , typeConfiguration )
825
908
: mappedSuperclassType ;
0 commit comments