Skip to content

Commit 96040d0

Browse files
committed
HHH-18714 add support for inheritance in NamedEntityGraph annotation
1 parent 36d6e46 commit 96040d0

File tree

3 files changed

+546
-31
lines changed

3 files changed

+546
-31
lines changed

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

Lines changed: 89 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
import static org.hibernate.metamodel.internal.InjectionHelper.injectTypedQueryReference;
7474

7575
/**
76-
*
7776
* @author Steve Ebersole
7877
*/
7978
public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
@@ -106,7 +105,7 @@ private ImportInfo(String importedName, Class<T> loadedClass) {
106105
private final Map<Class<?>, String> entityProxyInterfaceMap = new HashMap<>();
107106

108107
private final Map<String, ImportInfo<?>> nameToImportMap = new ConcurrentHashMap<>();
109-
private final Map<String,Object> knownInvalidnameToImportMap = new ConcurrentHashMap<>();
108+
private final Map<String, Object> knownInvalidnameToImportMap = new ConcurrentHashMap<>();
110109

111110

112111
public JpaMetamodelImpl(
@@ -143,13 +142,14 @@ public JpaCompliance getJpaCompliance() {
143142
public <X> ManagedDomainType<X> managedType(String typeName) {
144143
final ManagedDomainType<X> managedType = findManagedType( typeName );
145144
if ( managedType == null ) {
146-
throw new IllegalArgumentException("Not a managed type: " + typeName);
145+
throw new IllegalArgumentException( "Not a managed type: " + typeName );
147146
}
148147
return managedType;
149148
}
150149

151150
@Override
152-
@Nullable public EntityDomainType<?> findEntityType(@Nullable String entityName) {
151+
@Nullable
152+
public EntityDomainType<?> findEntityType(@Nullable String entityName) {
153153
if ( entityName == null ) {
154154
return null;
155155
}
@@ -162,18 +162,19 @@ public EntityDomainType<?> entity(String entityName) {
162162
final EntityDomainType<?> entityType = findEntityType( entityName );
163163
if ( entityType == null ) {
164164
// per JPA
165-
throw new IllegalArgumentException("Not an entity: " + entityName);
165+
throw new IllegalArgumentException( "Not an entity: " + entityName );
166166
}
167167
return entityType;
168168
}
169169

170170
@Override
171-
@Nullable public EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName) {
171+
@Nullable
172+
public EmbeddableDomainType<?> findEmbeddableType(@Nullable String embeddableName) {
172173
if ( embeddableName == null ) {
173174
return null;
174175
}
175176
final ManagedDomainType<?> managedType = managedTypeByName.get( embeddableName );
176-
if ( !( managedType instanceof EmbeddableDomainType<?> embeddableDomainType) ) {
177+
if ( !(managedType instanceof EmbeddableDomainType<?> embeddableDomainType) ) {
177178
return null;
178179
}
179180
return embeddableDomainType;
@@ -183,7 +184,7 @@ public EntityDomainType<?> entity(String entityName) {
183184
public EmbeddableDomainType<?> embeddable(String embeddableName) {
184185
final EmbeddableDomainType<?> embeddableType = findEmbeddableType( embeddableName );
185186
if ( embeddableType == null ) {
186-
throw new IllegalArgumentException("Not an embeddable: " + embeddableName);
187+
throw new IllegalArgumentException( "Not an embeddable: " + embeddableName );
187188
}
188189
return embeddableType;
189190
}
@@ -226,7 +227,8 @@ public <X> EntityDomainType<X> resolveHqlEntityReference(String entityName) {
226227
}
227228

228229
@Override
229-
@Nullable public <X> ManagedDomainType<X> findManagedType(Class<X> cls) {
230+
@Nullable
231+
public <X> ManagedDomainType<X> findManagedType(Class<X> cls) {
230232
//noinspection unchecked
231233
return (ManagedDomainType<X>) managedTypeByClass.get( cls );
232234
}
@@ -242,9 +244,10 @@ public <X> ManagedDomainType<X> managedType(Class<X> cls) {
242244
}
243245

244246
@Override
245-
@Nullable public <X> EntityDomainType<X> findEntityType(Class<X> cls) {
247+
@Nullable
248+
public <X> EntityDomainType<X> findEntityType(Class<X> cls) {
246249
final ManagedType<?> type = managedTypeByClass.get( cls );
247-
if ( !( type instanceof EntityDomainType<?> ) ) {
250+
if ( !(type instanceof EntityDomainType<?>) ) {
248251
return null;
249252
}
250253
//noinspection unchecked
@@ -263,7 +266,7 @@ public <X> EntityDomainType<X> entity(Class<X> cls) {
263266
@Override
264267
public @Nullable <X> EmbeddableDomainType<X> findEmbeddableType(Class<X> cls) {
265268
final ManagedType<?> type = managedTypeByClass.get( cls );
266-
if ( !( type instanceof EmbeddableDomainType<?> ) ) {
269+
if ( !(type instanceof EmbeddableDomainType<?>) ) {
267270
return null;
268271
}
269272
//noinspection unchecked
@@ -281,7 +284,7 @@ public <X> EmbeddableDomainType<X> embeddable(Class<X> cls) {
281284

282285
private Collection<ManagedDomainType<?>> getAllManagedTypes() {
283286
// should never happen
284-
return switch (jpaMetaModelPopulationSetting) {
287+
return switch ( jpaMetaModelPopulationSetting ) {
285288
case IGNORE_UNSUPPORTED -> managedTypeByClass.values();
286289
case ENABLED -> managedTypeByName.values();
287290
case DISABLED -> emptySet();
@@ -311,7 +314,7 @@ public Set<EmbeddableType<?>> getEmbeddables() {
311314

312315
@Override
313316
public @Nullable Set<String> getEnumTypesForValue(String enumValue) {
314-
return allowedEnumLiteralsToEnumTypeNames.get( enumValue);
317+
return allowedEnumLiteralsToEnumTypeNames.get( enumValue );
315318
}
316319

317320
@Override
@@ -388,7 +391,8 @@ public <T> void addNamedEntityGraph(String graphName, RootGraphImplementor<T> en
388391
}
389392
}
390393

391-
@Override @SuppressWarnings("unchecked")
394+
@Override
395+
@SuppressWarnings("unchecked")
392396
public <T> RootGraphImplementor<T> findEntityGraphByName(String name) {
393397
return (RootGraphImplementor<T>) entityGraphMap.get( name );
394398
}
@@ -490,21 +494,52 @@ private void applyNamedEntityGraphs(Collection<NamedEntityGraphDefinition> named
490494
if ( entityType == null ) {
491495
throw new IllegalArgumentException(
492496
"Attempted to register named entity graph [" + definition.getRegisteredName()
493-
+ "] for unknown entity [" + definition.getEntityName() + "]"
497+
+ "] for unknown entity [" + definition.getEntityName() + "]"
494498

495499
);
496500
}
501+
497502
final NamedEntityGraph namedEntityGraph = definition.getAnnotation();
498503
final RootGraphImpl<?> entityGraph =
499-
createRootGraph( definition.getRegisteredName(), entityType,
500-
namedEntityGraph.includeAllAttributes() );
501-
if ( namedEntityGraph.attributeNodes() != null ) {
502-
applyNamedAttributeNodes( namedEntityGraph.attributeNodes(), namedEntityGraph, entityGraph );
503-
}
504+
createEntityGraph(
505+
namedEntityGraph,
506+
definition.getRegisteredName(),
507+
entityType,
508+
namedEntityGraph.includeAllAttributes()
509+
);
510+
504511
entityGraphMap.put( definition.getRegisteredName(), entityGraph );
505512
}
506513
}
507514

515+
private <T> RootGraphImpl<T> createEntityGraph(
516+
NamedEntityGraph namedEntityGraph,
517+
String registeredName,
518+
EntityDomainType<T> entityType,
519+
boolean includeAllAttributes) {
520+
final RootGraphImpl<T> entityGraph =
521+
createRootGraph( registeredName, entityType, includeAllAttributes );
522+
523+
if ( namedEntityGraph.subclassSubgraphs() != null ) {
524+
for(var subclassSubgraph : namedEntityGraph.subclassSubgraphs()) {
525+
GraphImplementor<?> subgraph = (GraphImplementor<?>) entityGraph.addTreatedSubgraph(
526+
(Class) subclassSubgraph.type() );
527+
528+
applyNamedAttributeNodes(
529+
subclassSubgraph.attributeNodes(),
530+
namedEntityGraph,
531+
subgraph
532+
);
533+
}
534+
}
535+
536+
if ( namedEntityGraph.attributeNodes() != null ) {
537+
applyNamedAttributeNodes( namedEntityGraph.attributeNodes(), namedEntityGraph, entityGraph );
538+
}
539+
540+
return entityGraph;
541+
}
542+
508543
private static <T> RootGraphImpl<T> createRootGraph(
509544
String name, EntityDomainType<T> entityType, boolean includeAllAttributes) {
510545
final RootGraphImpl<T> entityGraph = new RootGraphImpl<>( name, entityType );
@@ -521,31 +556,41 @@ private void applyNamedAttributeNodes(
521556
NamedEntityGraph namedEntityGraph,
522557
GraphImplementor<?> graphNode) {
523558
for ( NamedAttributeNode namedAttributeNode : namedAttributeNodes ) {
524-
final AttributeNodeImplementor<?> attributeNode =
525-
graphNode.findOrCreateAttributeNode( namedAttributeNode.value() );
559+
final String value = namedAttributeNode.value();
560+
final AttributeNodeImplementor<?> attributeNode = (AttributeNodeImplementor<?>) graphNode.addAttributeNode( value );
561+
526562
if ( isNotEmpty( namedAttributeNode.subgraph() ) ) {
527563
applyNamedSubgraphs(
528564
namedEntityGraph,
529565
namedAttributeNode.subgraph(),
530-
attributeNode.makeSubGraph()
566+
attributeNode,
567+
false
531568
);
532569
}
533570
if ( isNotEmpty( namedAttributeNode.keySubgraph() ) ) {
534571
applyNamedSubgraphs(
535572
namedEntityGraph,
536573
namedAttributeNode.keySubgraph(),
537-
attributeNode.makeKeySubGraph()
574+
attributeNode,
575+
true
538576
);
539577
}
540578
}
541579
}
542580

543-
private void applyNamedSubgraphs(
581+
@SuppressWarnings({"unchecked", "rawtypes"})
582+
private <T> void applyNamedSubgraphs(
544583
NamedEntityGraph namedEntityGraph,
545584
String subgraphName,
546-
SubGraphImplementor<?> subgraph) {
585+
AttributeNodeImplementor<T> attributeNode, Boolean isKeySubGraph) {
547586
for ( NamedSubgraph namedSubgraph : namedEntityGraph.subgraphs() ) {
548587
if ( subgraphName.equals( namedSubgraph.name() ) ) {
588+
var isDefaultSubgraphType = namedSubgraph.type().equals( void.class );
589+
Class subGraphType = isDefaultSubgraphType ? null : namedSubgraph.type();
590+
591+
final SubGraphImplementor<?> subgraph = makeAttributeNodeSubgraph( attributeNode, isKeySubGraph,
592+
subGraphType );
593+
549594
applyNamedAttributeNodes(
550595
namedSubgraph.attributeNodes(),
551596
namedEntityGraph,
@@ -555,6 +600,18 @@ private void applyNamedSubgraphs(
555600
}
556601
}
557602

603+
private static <T> SubGraphImplementor<?> makeAttributeNodeSubgraph(AttributeNodeImplementor<T> attributeNode, Boolean isKeySubGraph, Class<T> subGraphType) {
604+
605+
if ( isKeySubGraph ) {
606+
return subGraphType != null ? attributeNode.makeKeySubGraph( subGraphType )
607+
: attributeNode.makeKeySubGraph();
608+
}
609+
610+
return subGraphType != null ?
611+
attributeNode.makeSubGraph( subGraphType ) :
612+
attributeNode.makeSubGraph();
613+
}
614+
558615
private <X> Class<X> resolveRequestedClass(String entityName) {
559616
try {
560617
return getServiceRegistry().requireService( ClassLoaderService.class )
@@ -609,8 +666,8 @@ public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
609666
// incorrect results
610667
final ManagedDomainType<?> superType = managedType.getSuperType();
611668
if ( superType != null
612-
&& superType.getPersistenceType() == Type.PersistenceType.ENTITY
613-
&& javaType.isAssignableFrom( superType.getJavaType() ) ) {
669+
&& superType.getPersistenceType() == Type.PersistenceType.ENTITY
670+
&& javaType.isAssignableFrom( superType.getJavaType() ) ) {
614671
continue;
615672
}
616673

@@ -631,7 +688,8 @@ public <T> EntityDomainType<T> resolveEntityReference(Class<T> javaType) {
631688
}
632689
}
633690

634-
throw new EntityTypeException( "Could not resolve entity class '" + javaType.getName() + "'", javaType.getName() );
691+
throw new EntityTypeException( "Could not resolve entity class '" + javaType.getName() + "'",
692+
javaType.getName() );
635693
}
636694

637695
@Override
@@ -719,7 +777,7 @@ private void populateStaticMetamodel(MetadataImplementor bootMetamodel, Metadata
719777
-> injectTypedQueryReference( definition, namedQueryMetamodelClass( definition, context ) ) );
720778
bootMetamodel.visitNamedNativeQueryDefinitions( definition
721779
-> injectTypedQueryReference( definition, namedQueryMetamodelClass( definition, context ) ) );
722-
bootMetamodel.getNamedEntityGraphs().values().forEach(definition
780+
bootMetamodel.getNamedEntityGraphs().values().forEach( definition
723781
-> injectEntityGraph( definition, graphMetamodelClass( definition, context ), this ) );
724782
}
725783

0 commit comments

Comments
 (0)