7878 * corresponding Class property. 
7979 * <li>{@code DataFetcher} registrations refer to a schema field that exists. 
8080 * <li>{@code DataFetcher} arguments have matching schema field arguments. 
81-  * <li>The nullness of schema fields matches the nullness of {@link DataFetcher} 
82-  * return types, class properties or class methods. 
83-  * <li>{@code DataFetcher} arguments match the nullness of schema argument types. 
81+  * <li>The nullness of {@link DataFetcher} return types, class properties or class methods 
82+  * match, or is more restrictive than, the nullness of schema fields. 
83+  * <li>The nullness of {@code DataFetcher} arguments match, or is more restrictive than, 
84+  * the nullness of schema argument types. 
8485 * </ul> 
8586 * 
8687 * <p>Use methods of {@link GraphQlSource.SchemaResourceBuilder} to enable schema 
@@ -223,11 +224,11 @@ private void checkFieldsContainer(
223224
224225	private  void  checkFieldNullNess (FieldCoordinates  fieldCoordinates , Field  javaField , Nullness  schemaNullness ) {
225226		Nullness  applicationNullness  = Nullness .forField (javaField );
226- 		if  (isMismatch (schemaNullness , applicationNullness )) {
227+ 		if  (isNullnessError (schemaNullness , applicationNullness )) {
227228			DescribedAnnotatedElement  annotatedElement  = new  DescribedAnnotatedElement (javaField ,
228229					javaField .getDeclaringClass ().getSimpleName () + "#"  + javaField .getName ());
229- 			this .reportBuilder .fieldNullnessMismatch (fieldCoordinates ,
230- 					new  DefaultNullnessMismatch (schemaNullness , applicationNullness , annotatedElement ));
230+ 			this .reportBuilder .fieldNullnessError (fieldCoordinates ,
231+ 					new  DefaultNullnessError (schemaNullness , applicationNullness , annotatedElement ));
231232
232233		}
233234	}
@@ -246,10 +247,10 @@ else if (dataFetcher.usesDataLoader() && Map.class.isAssignableFrom(dataFetcherM
246247				// we cannot infer nullness if batch loader method returns a Map 
247248				logger .debug ("Skip nullness check for data fetcher '"  + dataFetcherMethod .getName () + "' because of batch loading." );
248249			}
249- 			else  if  (isMismatch (schemaNullness , applicationNullness )) {
250+ 			else  if  (isNullnessError (schemaNullness , applicationNullness )) {
250251				DescribedAnnotatedElement  annotatedElement  = new  DescribedAnnotatedElement (dataFetcherMethod , dataFetcher .getDescription ());
251- 				this .reportBuilder .fieldNullnessMismatch (fieldCoordinates ,
252- 						new  DefaultNullnessMismatch (schemaNullness , applicationNullness , annotatedElement ));
252+ 				this .reportBuilder .fieldNullnessError (fieldCoordinates ,
253+ 						new  DefaultNullnessError (schemaNullness , applicationNullness , annotatedElement ));
253254
254255			}
255256		}
@@ -270,30 +271,30 @@ private void checkFieldArguments(GraphQLFieldDefinition field, SelfDescribingDat
270271	private  void  checkFieldArgumentsNullness (GraphQLFieldDefinition  field , SelfDescribingDataFetcher <?> dataFetcher ) {
271272		Method  dataFetcherMethod  = dataFetcher .asMethod ();
272273		if  (dataFetcherMethod  != null ) {
273- 			List <SchemaReport .NullnessMismatch >  mismatches  = new  ArrayList <>();
274+ 			List <SchemaReport .NullnessError >  nullnessErrors  = new  ArrayList <>();
274275			for  (Parameter  parameter  : dataFetcherMethod .getParameters ()) {
275276				GraphQLArgument  argument  = field .getArgument (parameter .getName ());
276- 				if  (argument  != null ) {
277+ 				if  (argument  != null  &&  argument . getDefinition () !=  null ) {
277278					Nullness  schemaNullness  = resolveNullness (argument .getDefinition ().getType ());
278279					Nullness  applicationNullness  = Nullness .forMethodParameter (MethodParameter .forParameter (parameter ));
279- 					if  (isMismatch (schemaNullness , applicationNullness )) {
280- 						mismatches .add (new  DefaultNullnessMismatch (schemaNullness , applicationNullness , parameter ));
280+ 					if  (isNullnessError (schemaNullness , applicationNullness )) {
281+ 						nullnessErrors .add (new  DefaultNullnessError (schemaNullness , applicationNullness , parameter ));
281282					}
282283				}
283284			}
284- 			if  (!mismatches .isEmpty ()) {
285- 				this .reportBuilder .argumentsNullnessMismatches (dataFetcher , mismatches );
285+ 			if  (!nullnessErrors .isEmpty ()) {
286+ 				this .reportBuilder .argumentsNullnessErrors (dataFetcher , nullnessErrors );
286287			}
287288		}
288289	}
289290
290291	private  void  checkReadMethodNullness (FieldCoordinates  fieldCoordinates , ResolvableType  resolvableType , PropertyDescriptor  descriptor , Nullness  schemaNullness ) {
291292		Nullness  applicationNullness  = Nullness .forMethodReturnType (descriptor .getReadMethod ());
292- 		if  (isMismatch (schemaNullness , applicationNullness )) {
293+ 		if  (isNullnessError (schemaNullness , applicationNullness )) {
293294			DescribedAnnotatedElement  annotatedElement  = new  DescribedAnnotatedElement (descriptor .getReadMethod (),
294295					resolvableType .toClass ().getSimpleName () + "#"  + descriptor .getName ());
295- 			this .reportBuilder .fieldNullnessMismatch (fieldCoordinates ,
296- 					new  DefaultNullnessMismatch (schemaNullness , applicationNullness , annotatedElement ));
296+ 			this .reportBuilder .fieldNullnessError (fieldCoordinates ,
297+ 					new  DefaultNullnessError (schemaNullness , applicationNullness , annotatedElement ));
297298		}
298299	}
299300
@@ -408,12 +409,11 @@ private Nullness resolveNullness(Type type) {
408409		if  (type  instanceof  NonNullType ) {
409410			return  Nullness .NON_NULL ;
410411		}
411- 		return    Nullness .NULLABLE ;
412+ 		return  Nullness .NULLABLE ;
412413	}
413414
414- 	private  boolean  isMismatch (Nullness  first , Nullness  second ) {
415- 		return  (first  == Nullness .NON_NULL  && second  == Nullness .NULLABLE ) ||
416- 				(first  == Nullness .NULLABLE  && second  == Nullness .NON_NULL );
415+ 	private  boolean  isNullnessError (Nullness  schemaNullness , Nullness  applicationNullness ) {
416+ 		return  (schemaNullness  == Nullness .NON_NULL  && applicationNullness  == Nullness .NULLABLE );
417417	}
418418
419419
@@ -909,9 +909,9 @@ private final class ReportBuilder {
909909
910910		private  final  MultiValueMap <DataFetcher <?>, String > unmappedArguments  = new  LinkedMultiValueMap <>();
911911
912- 		private  final  Map <FieldCoordinates , SchemaReport .NullnessMismatch >  fieldNullnessMismatches  = new  LinkedHashMap <>();
912+ 		private  final  Map <FieldCoordinates , SchemaReport .NullnessError >  fieldNullnessErrors  = new  LinkedHashMap <>();
913913
914- 		private  final  MultiValueMap <DataFetcher <?>, SchemaReport .NullnessMismatch >  argumentsNullnessMismatches  = new  LinkedMultiValueMap <>();
914+ 		private  final  MultiValueMap <DataFetcher <?>, SchemaReport .NullnessError >  argumentsNullnessErrors  = new  LinkedMultiValueMap <>();
915915
916916		private  final  List <DefaultSkippedType > skippedTypes  = new  ArrayList <>();
917917
@@ -929,12 +929,12 @@ void unmappedArgument(DataFetcher<?> dataFetcher, List<String> arguments) {
929929			this .unmappedArguments .put (dataFetcher , arguments );
930930		}
931931
932- 		void  fieldNullnessMismatch (FieldCoordinates  coordinates , SchemaReport .NullnessMismatch   nullnessMismatch ) {
933- 			this .fieldNullnessMismatches .put (coordinates , nullnessMismatch );
932+ 		void  fieldNullnessError (FieldCoordinates  coordinates , SchemaReport .NullnessError   nullnessError ) {
933+ 			this .fieldNullnessErrors .put (coordinates , nullnessError );
934934		}
935935
936- 		void  argumentsNullnessMismatches (DataFetcher <?> dataFetcher , List <SchemaReport .NullnessMismatch >  nullnessMismatches ) {
937- 			this .argumentsNullnessMismatches .put (dataFetcher , nullnessMismatches );
936+ 		void  argumentsNullnessErrors (DataFetcher <?> dataFetcher , List <SchemaReport .NullnessError >  nullnessErrors ) {
937+ 			this .argumentsNullnessErrors .put (dataFetcher , nullnessErrors );
938938		}
939939
940940		void  skippedType (
@@ -973,7 +973,7 @@ SchemaReport build() {
973973			});
974974
975975			return  new  DefaultSchemaReport (this .unmappedFields , this .unmappedRegistrations ,
976- 					this .unmappedArguments , this .fieldNullnessMismatches , this .argumentsNullnessMismatches , this .skippedTypes );
976+ 					this .unmappedArguments , this .fieldNullnessErrors , this .argumentsNullnessErrors , this .skippedTypes );
977977		}
978978	}
979979
@@ -989,24 +989,24 @@ private final class DefaultSchemaReport implements SchemaReport {
989989
990990		private  final  MultiValueMap <DataFetcher <?>, String > unmappedArguments ;
991991
992- 		private  final  Map <FieldCoordinates , NullnessMismatch >  fieldsNullnessMismatches ;
992+ 		private  final  Map <FieldCoordinates , NullnessError >  fieldNullnessErrors ;
993993
994- 		private  final  MultiValueMap <DataFetcher <?>, NullnessMismatch >  argumentsNullnessMismatches ;
994+ 		private  final  MultiValueMap <DataFetcher <?>, NullnessError >  argumentNullnessErrors ;
995995
996996		private  final  List <SchemaReport .SkippedType > skippedTypes ;
997997
998998		DefaultSchemaReport (
999999				List <FieldCoordinates > unmappedFields , Map <FieldCoordinates , DataFetcher <?>> unmappedRegistrations ,
10001000				MultiValueMap <DataFetcher <?>, String > unmappedArguments ,
1001- 				Map <FieldCoordinates , NullnessMismatch >  fieldsNullnessMismatches ,
1002- 				MultiValueMap <DataFetcher <?>, NullnessMismatch >  argumentsNullnessMismatches ,
1001+ 				Map <FieldCoordinates , NullnessError >  fieldNullnessErrors ,
1002+ 				MultiValueMap <DataFetcher <?>, NullnessError >  argumentNullnessErrors ,
10031003				List <DefaultSkippedType > skippedTypes ) {
10041004
10051005			this .unmappedFields  = Collections .unmodifiableList (unmappedFields );
10061006			this .unmappedRegistrations  = Collections .unmodifiableMap (unmappedRegistrations );
10071007			this .unmappedArguments  = CollectionUtils .unmodifiableMultiValueMap (unmappedArguments );
1008- 			this .fieldsNullnessMismatches  = Collections .unmodifiableMap (fieldsNullnessMismatches );
1009- 			this .argumentsNullnessMismatches  = CollectionUtils .unmodifiableMultiValueMap (argumentsNullnessMismatches );
1008+ 			this .fieldNullnessErrors  = Collections .unmodifiableMap (fieldNullnessErrors );
1009+ 			this .argumentNullnessErrors  = CollectionUtils .unmodifiableMultiValueMap (argumentNullnessErrors );
10101010			this .skippedTypes  = Collections .unmodifiableList (skippedTypes );
10111011		}
10121012
@@ -1026,13 +1026,13 @@ public MultiValueMap<DataFetcher<?>, String> unmappedArguments() {
10261026		}
10271027
10281028		@ Override 
1029- 		public  Map <FieldCoordinates , NullnessMismatch >  fieldsNullnessMismatches () {
1030- 			return  this .fieldsNullnessMismatches ;
1029+ 		public  Map <FieldCoordinates , NullnessError >  fieldNullnessErrors () {
1030+ 			return  this .fieldNullnessErrors ;
10311031		}
10321032
10331033		@ Override 
1034- 		public  MultiValueMap <DataFetcher <?>, NullnessMismatch >  argumentsNullnessMismatches () {
1035- 			return  this .argumentsNullnessMismatches ;
1034+ 		public  MultiValueMap <DataFetcher <?>, NullnessError >  argumentNullnessErrors () {
1035+ 			return  this .argumentNullnessErrors ;
10361036		}
10371037
10381038		@ Override 
@@ -1058,8 +1058,8 @@ public String toString() {
10581058					"\t Unmapped fields: "  + formatUnmappedFields () + "\n "  +
10591059					"\t Unmapped registrations: "  + this .unmappedRegistrations  + "\n "  +
10601060					"\t Unmapped arguments: "  + this .unmappedArguments  + "\n "  +
1061- 					"\t  Fields  nullness mismatches : "  + formatFieldsNullnessMismatches () + "\n "  +
1062- 					"\t  Arguments  nullness mismatches : "  + formatArgumentsNullnessMismatches () + "\n "  +
1061+ 					"\t  Field  nullness errors : "  + formatFieldNullnessErrors () + "\n "  +
1062+ 					"\t  Argument  nullness errors : "  + formatArgumentNullnessErrors () + "\n "  +
10631063					"\t Skipped types: "  + this .skippedTypes ;
10641064		}
10651065
@@ -1072,21 +1072,21 @@ private String formatUnmappedFields() {
10721072			return  map .toString ();
10731073		}
10741074
1075- 		private  String  formatFieldsNullnessMismatches () {
1075+ 		private  String  formatFieldNullnessErrors () {
10761076			MultiValueMap <String , String > map  = new  LinkedMultiValueMap <>();
1077- 			this .fieldsNullnessMismatches .forEach ((coordinates , mismatch ) -> {
1077+ 			this .fieldNullnessErrors .forEach ((coordinates , nullnessError ) -> {
10781078				List <String > fields  = map .computeIfAbsent (coordinates .getTypeName (), (s ) -> new  ArrayList <>());
1079- 				fields .add (String .format ("%s is %s -> '%s' is %s" , coordinates .getFieldName (), mismatch .schemaNullness (),
1080- 						mismatch .annotatedElement (), mismatch .applicationNullness ()));
1079+ 				fields .add (String .format ("%s is %s -> '%s' is %s" , coordinates .getFieldName (), nullnessError .schemaNullness (),
1080+ 						nullnessError .annotatedElement (), nullnessError .applicationNullness ()));
10811081			});
10821082			return  map .toString ();
10831083		}
10841084
1085- 		private  String  formatArgumentsNullnessMismatches () {
1085+ 		private  String  formatArgumentNullnessErrors () {
10861086			MultiValueMap <String , String > map  = new  LinkedMultiValueMap <>();
1087- 			this .argumentsNullnessMismatches .forEach ((dataFetcher , mismatches ) -> {
1088- 				List <String > arguments  = mismatches .stream ()
1089- 						.map ((mismatch ) -> String .format ("%s should be %s" , mismatch .annotatedElement (), mismatch .schemaNullness ()))
1087+ 			this .argumentNullnessErrors .forEach ((dataFetcher , nullnessErrors ) -> {
1088+ 				List <String > arguments  = nullnessErrors .stream ()
1089+ 						.map ((nullnessError ) -> String .format ("%s should be %s" , nullnessError .annotatedElement (), nullnessError .schemaNullness ()))
10901090						.toList ();
10911091				map .put (dataFetcher .toString (), arguments );
10921092			});
@@ -1116,11 +1116,11 @@ public static DefaultSkippedType create(
11161116	}
11171117
11181118	/** 
1119- 	 * Default implementation of a {@link SchemaReport.NullnessMismatch }. 
1119+ 	 * Default implementation of a {@link SchemaReport.NullnessError }. 
11201120	 */ 
1121- 	private  record  DefaultNullnessMismatch (
1121+ 	private  record  DefaultNullnessError (
11221122			Nullness  schemaNullness , Nullness  applicationNullness , AnnotatedElement  annotatedElement )
1123- 			implements  SchemaReport .NullnessMismatch  {
1123+ 			implements  SchemaReport .NullnessError  {
11241124
11251125	}
11261126
0 commit comments