Skip to content

Commit 4251dd8

Browse files
Asanio06gavinking
authored andcommitted
HHH-18714 add support for inheritance in NamedEntityGraph annotation
1 parent 36d6e46 commit 4251dd8

File tree

3 files changed

+574
-34
lines changed

3 files changed

+574
-34
lines changed

hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/JpaMetamodelImpl.java

+117-34
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.stream.Collectors;
2121

2222
import org.checkerframework.checker.nullness.qual.Nullable;
23+
2324
import org.hibernate.boot.model.NamedEntityGraphDefinition;
2425
import org.hibernate.boot.query.NamedQueryDefinition;
2526
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
@@ -73,7 +74,6 @@
7374
import static org.hibernate.metamodel.internal.InjectionHelper.injectTypedQueryReference;
7475

7576
/**
76-
*
7777
* @author Steve Ebersole
7878
*/
7979
public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
@@ -106,7 +106,7 @@ private ImportInfo(String importedName, Class<T> loadedClass) {
106106
private final Map<Class<?>, String> entityProxyInterfaceMap = new HashMap<>();
107107

108108
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<>();
110110

111111

112112
public JpaMetamodelImpl(
@@ -143,13 +143,14 @@ public JpaCompliance getJpaCompliance() {
143143
public <X> ManagedDomainType<X> managedType(String typeName) {
144144
final ManagedDomainType<X> managedType = findManagedType( typeName );
145145
if ( managedType == null ) {
146-
throw new IllegalArgumentException("Not a managed type: " + typeName);
146+
throw new IllegalArgumentException( "Not a managed type: " + typeName );
147147
}
148148
return managedType;
149149
}
150150

151151
@Override
152-
@Nullable public EntityDomainType<?> findEntityType(@Nullable String entityName) {
152+
@Nullable
153+
public EntityDomainType<?> findEntityType(@Nullable String entityName) {
153154
if ( entityName == null ) {
154155
return null;
155156
}
@@ -162,18 +163,19 @@ public EntityDomainType<?> entity(String entityName) {
162163
final EntityDomainType<?> entityType = findEntityType( entityName );
163164
if ( entityType == null ) {
164165
// per JPA
165-
throw new IllegalArgumentException("Not an entity: " + entityName);
166+
throw new IllegalArgumentException( "Not an entity: " + entityName );
166167
}
167168
return entityType;
168169
}
169170

170171
@Override
171-
@Nullable public EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName) {
172+
@Nullable
173+
public EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName) {
172174
if ( embeddableName == null ) {
173175
return null;
174176
}
175177
final ManagedDomainType<?> managedType = managedTypeByName.get( embeddableName );
176-
if ( !( managedType instanceof EmbeddableDomainType<?> embeddableDomainType) ) {
178+
if ( !( managedType instanceof EmbeddableDomainType<?> embeddableDomainType ) ) {
177179
return null;
178180
}
179181
return embeddableDomainType;
@@ -183,7 +185,7 @@ public EntityDomainType<?> entity(String entityName) {
183185
public EmbeddableDomainType<?> embeddable(String embeddableName) {
184186
final EmbeddableDomainType<?> embeddableType = findEmbeddableType( embeddableName );
185187
if ( embeddableType == null ) {
186-
throw new IllegalArgumentException("Not an embeddable: " + embeddableName);
188+
throw new IllegalArgumentException( "Not an embeddable: " + embeddableName );
187189
}
188190
return embeddableType;
189191
}
@@ -226,7 +228,8 @@ public <X> EntityDomainType<X> resolveHqlEntityReference(String entityName) {
226228
}
227229

228230
@Override
229-
@Nullable public <X> ManagedDomainType<X> findManagedType(Class<X> cls) {
231+
@Nullable
232+
public <X> ManagedDomainType<X> findManagedType(Class<X> cls) {
230233
//noinspection unchecked
231234
return (ManagedDomainType<X>) managedTypeByClass.get( cls );
232235
}
@@ -242,7 +245,8 @@ public <X> ManagedDomainType<X> managedType(Class<X> cls) {
242245
}
243246

244247
@Override
245-
@Nullable public <X> EntityDomainType<X> findEntityType(Class<X> cls) {
248+
@Nullable
249+
public <X> EntityDomainType<X> findEntityType(Class<X> cls) {
246250
final ManagedType<?> type = managedTypeByClass.get( cls );
247251
if ( !( type instanceof EntityDomainType<?> ) ) {
248252
return null;
@@ -281,7 +285,7 @@ public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
281285

282286
private Collection<ManagedDomainType<?>> getAllManagedTypes() {
283287
// should never happen
284-
return switch (jpaMetaModelPopulationSetting) {
288+
return switch ( jpaMetaModelPopulationSetting ) {
285289
case IGNORE_UNSUPPORTED -> managedTypeByClass.values();
286290
case ENABLED -> managedTypeByName.values();
287291
case DISABLED -> emptySet();
@@ -311,7 +315,7 @@ public Set<EmbeddableType<?>> getEmbeddables() {
311315

312316
@Override
313317
public @Nullable Set<String> getEnumTypesForValue(String enumValue) {
314-
return allowedEnumLiteralsToEnumTypeNames.get( enumValue);
318+
return allowedEnumLiteralsToEnumTypeNames.get( enumValue );
315319
}
316320

317321
@Override
@@ -388,7 +392,8 @@ public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> en
388392
}
389393
}
390394

391-
@Override @SuppressWarnings("unchecked")
395+
@Override
396+
@SuppressWarnings("unchecked")
392397
public <T> RootGraphImplementor<T> findEntityGraphByName(String name) {
393398
return (RootGraphImplementor<T>) entityGraphMap.get( name );
394399
}
@@ -494,17 +499,48 @@ private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> named
494499

495500
);
496501
}
502+
497503
final NamedEntityGraph namedEntityGraph = definition.getAnnotation();
498504
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+
504512
entityGraphMap.put( definition.getRegisteredName(), entityGraph );
505513
}
506514
}
507515

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+
508544
private static <T> RootGraphImpl<T> createRootGraph(
509545
String name, EntityDomainType<T> entityType, boolean includeAllAttributes) {
510546
final RootGraphImpl<T> entityGraph = new RootGraphImpl<>( name, entityType );
@@ -521,31 +557,44 @@ private void applyNamedAttributeNodes(
521557
NamedEntityGraph namedEntityGraph,
522558
GraphImplementor<?> graphNode) {
523559
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+
526564
if ( isNotEmpty( namedAttributeNode.subgraph() ) ) {
527565
applyNamedSubgraphs(
528566
namedEntityGraph,
529567
namedAttributeNode.subgraph(),
530-
attributeNode.makeSubGraph()
568+
attributeNode,
569+
false
531570
);
532571
}
533572
if ( isNotEmpty( namedAttributeNode.keySubgraph() ) ) {
534573
applyNamedSubgraphs(
535574
namedEntityGraph,
536575
namedAttributeNode.keySubgraph(),
537-
attributeNode.makeKeySubGraph()
576+
attributeNode,
577+
true
538578
);
539579
}
540580
}
541581
}
542582

543-
private void applyNamedSubgraphs(
583+
@SuppressWarnings({ "unchecked", "rawtypes" })
584+
private <T> void applyNamedSubgraphs(
544585
NamedEntityGraph namedEntityGraph,
545586
String subgraphName,
546-
SubGraphImplementor<?> subgraph) {
587+
AttributeNodeImplementor<T> attributeNode, Boolean isKeySubGraph) {
547588
for ( NamedSubgraph namedSubgraph : namedEntityGraph.subgraphs() ) {
548589
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+
549598
applyNamedAttributeNodes(
550599
namedSubgraph.attributeNodes(),
551600
namedEntityGraph,
@@ -555,6 +604,21 @@ private void applyNamedSubgraphs(
555604
}
556605
}
557606

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+
558622
private <X> Class<X> resolveRequestedClass(String entityName) {
559623
try {
560624
return getServiceRegistry().requireService( ClassLoaderService.class )
@@ -631,7 +695,10 @@ public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
631695
}
632696
}
633697

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+
);
635702
}
636703

637704
@Override
@@ -716,11 +783,30 @@ public void processJpa(
716783

717784
private void populateStaticMetamodel(MetadataImplementor bootMetamodel, MetadataContext context) {
718785
bootMetamodel.visitNamedHqlQueryDefinitions( definition
719-
-> injectTypedQueryReference( definition, namedQueryMetamodelClass( definition, context ) ) );
786+
-> injectTypedQueryReference(
787+
definition,
788+
namedQueryMetamodelClass(
789+
definition,
790+
context
791+
)
792+
) );
720793
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+
) );
724810
}
725811

726812
private Class<?> namedQueryMetamodelClass(NamedQueryDefinition<?> definition, MetadataContext context) {
@@ -764,9 +850,7 @@ private <T> EntityDomainType<T> locateOrBuildEntityType(
764850
MetadataContext context,
765851
final TypeConfiguration typeConfiguration) {
766852
@SuppressWarnings("unchecked")
767-
final EntityDomainType<T> entityType =
768-
(EntityDomainType<T>)
769-
context.locateEntityType( persistentClass );
853+
final EntityDomainType<T> entityType = (EntityDomainType<T>) context.locateEntityType( persistentClass );
770854
return entityType == null
771855
? buildEntityType( persistentClass, context, typeConfiguration )
772856
: entityType;
@@ -818,8 +902,7 @@ private <T> MappedSuperclassDomainType<T> locateOrBuildMappedSuperclassType(
818902
TypeConfiguration typeConfiguration) {
819903
@SuppressWarnings("unchecked")
820904
final MappedSuperclassDomainType<T> mappedSuperclassType =
821-
(MappedSuperclassDomainType<T>)
822-
context.locateMappedSuperclassType( mappedSuperclass );
905+
(MappedSuperclassDomainType<T>) context.locateMappedSuperclassType( mappedSuperclass );
823906
return mappedSuperclassType == null
824907
? buildMappedSuperclassType( mappedSuperclass, context, typeConfiguration )
825908
: mappedSuperclassType;

0 commit comments

Comments
 (0)