Skip to content

Commit

Permalink
prevent fetching the whole subtree also for __typename of a union type
Browse files Browse the repository at this point in the history
  • Loading branch information
david-kubecka committed Jan 11, 2023
1 parent 424fb17 commit cdb7fb1
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -636,9 +636,14 @@ public void applyFetches(DataFetchingEnvironment dataFetchingEnvironment, Entity
// its id field. Otherwise, skip this fieldPart and effectively put the intermediate field path
// into fetches - in reality this wouldn't lead to any unnecessary joins since the EV in that case
// corresponds to an embeddable entity.
ManagedViewType<?> managedViewType = typeNameToViewType.get(typeName);
if (managedViewType instanceof ViewType) {
mappedFields.add(((ViewType<?>) managedViewType).getIdAttribute().getName());
for (String metaFieldTypeName: field.getObjectTypeNames()) {
// Meta field might have more parent types (in case of a union type). Try to find a first
// ViewType among them and use its id field to ensure the type info can be obtained from DB.
ManagedViewType<?> managedViewType = typeNameToViewType.get(metaFieldTypeName);
if (managedViewType instanceof ViewType) {
mappedFields.add(((ViewType<?>) managedViewType).getIdAttribute().getName());
break;
}
}
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class GraphQLEntityViewSupportTest {
public void testFetchesInSetting() {
GraphQLFieldDefinition rootFieldDefinition = makeFieldDefinition("getDocument", documentObjectType);
DataFetchingFieldSelectionSet selectionSet =
makeMockSelectionSet("Document", "name", "owner", "owner/name", "__typename");
makeMockSelectionSet("Document", "name", "owner", "owner/name", "Document.__typename");

DataFetchingEnvironment dfe = makeMockDataFetchingEnvironment(rootFieldDefinition, selectionSet);

Expand All @@ -78,13 +78,13 @@ public void testFetchesInPaginatedSetting() {
@Test
public void testRootUnionInSelectionSet() {
GraphQLFieldDefinition rootFieldDefinition = makeFieldDefinition("getAnimal", animalUnionType);
DataFetchingFieldSelectionSet selectionSet = makeMockSelectionSet("Cat", "name");
DataFetchingFieldSelectionSet selectionSet = makeMockSelectionSet("Cat", "name", "[Cat,Animal].__typename");

DataFetchingEnvironment dfe = makeMockDataFetchingEnvironment(rootFieldDefinition, selectionSet);

EntityViewSetting<AnimalView, CriteriaBuilder<AnimalView>> setting = graphQLEntityViewSupport.createSetting(dfe);

Assert.assertEquals(new HashSet<>(Arrays.asList("name")), setting.getFetches());
Assert.assertEquals(new HashSet<>(Arrays.asList("id", "name")), setting.getFetches());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public static DataFetchingFieldSelectionSet makeMockSelectionSet(String rootType
if (fieldPart.contains(".")) {
// provided fieldPart is already fully qualified
qualifiedFieldParts.add(fieldPart);
baseType = (fieldPart.split("\\."))[0];
baseType = getBaseTypes(fieldPart)[0];
fieldPart = (fieldPart.split("\\."))[1];
} else {
qualifiedFieldParts.add(baseType + "." + fieldPart);
Expand All @@ -129,6 +129,7 @@ public static DataFetchingFieldSelectionSet makeMockSelectionSet(String rootType
SelectedField selectedField = mock(SelectedField.class);
when(selectedField.getFullyQualifiedName()).thenReturn(String.join("/", qualifiedFieldParts));
when(selectedField.getType()).thenReturn(fieldType);
when(selectedField.getObjectTypeNames()).thenReturn(Arrays.asList(getBaseTypes(fieldParts[fieldParts.length-1])));
return selectedField;
}).collect(Collectors.toList());

Expand All @@ -137,6 +138,10 @@ public static DataFetchingFieldSelectionSet makeMockSelectionSet(String rootType
return selectionSet;
}

private static String[] getBaseTypes(String fieldPart) {
return (fieldPart.split("\\."))[0].replaceFirst("^\\[", "").replaceFirst("]$", "").split(",");
}

public static GraphQLEntityViewSupport getGraphQLEntityViewSupport() {
TypeDef documentTypeDef = new TypeDef("Document", DocumentView.class, Arrays.asList("id", "name", "owner"));
TypeDef personTypeDef = new TypeDef("Person", PersonView.class, Arrays.asList("id", "name", "animal"));
Expand Down

0 comments on commit cdb7fb1

Please sign in to comment.