From 454c0415462c41b8034a0a9d8cdf30f9fcd08af0 Mon Sep 17 00:00:00 2001 From: Koen Punt Date: Wed, 6 Oct 2021 11:37:52 +0200 Subject: [PATCH] Recursively instantiate beans in arguments This commit ensures that Java beans using primary constructors are properly instantiated when they're nested and that the instantiation algorithm is called recursively. Fixes gh-155 --- .../support/GraphQlArgumentInstantiator.java | 4 ++- .../GraphQlArgumentInstantiatorTests.java | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiator.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiator.java index 75fef488..eb51f487 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiator.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiator.java @@ -89,7 +89,9 @@ class GraphQlArgumentInstantiator { Class elementType = typeDescriptor.getElementTypeDescriptor().getType(); args[i] = instantiateCollection(elementType, (Collection) value); } - else { + else if (value instanceof Map) { + args[i] = this.instantiate((Map) value, methodParam.getParameterType()); + } else { args[i] = this.converter.convertIfNecessary(value, paramTypes[i], methodParam); } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiatorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiatorTests.java index 3f01cd15..bdd2e99b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiatorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/GraphQlArgumentInstantiatorTests.java @@ -103,6 +103,17 @@ class GraphQlArgumentInstantiatorTests { assertThat(result.getItems()).hasSize(2).extracting("name").containsExactly("first", "second"); } + @Test + void shouldInstantiateComplexNestedBean() throws Exception { + String payload = "{\"complex\": { \"item\": {\"name\": \"Item name\"}, \"name\": \"Hello\" } }"; + DataFetchingEnvironment environment = initEnvironment(payload); + PrimaryConstructorComplexInput result = instantiator.instantiate(environment.getArgument("complex"), PrimaryConstructorComplexInput.class); + + assertThat(result).isNotNull().isInstanceOf(PrimaryConstructorComplexInput.class); + assertThat(result.item.name).isEqualTo("Item name"); + assertThat(result.name).isEqualTo("Hello"); + } + private DataFetchingEnvironment initEnvironment(String jsonPayload) throws JsonProcessingException { Map arguments = this.mapper.readValue(jsonPayload, new TypeReference>() { }); @@ -182,5 +193,24 @@ class GraphQlArgumentInstantiatorTests { this.name = name; } } + + static class PrimaryConstructorComplexInput { + final String name; + + final Item item; + + public PrimaryConstructorComplexInput(String name, Item item) { + this.name = name; + this.item = item; + } + + public String getName() { + return this.name; + } + + public Item getItem() { + return item; + } + } } \ No newline at end of file