Skip to content

[Bug]: Cannot return null for non-nullable field. #1747

@yorek

Description

@yorek

What happened?

If, in a One-to-Many or Many-to-One relationship, there is no value for the "one" side of the relationship, an error is returned, instead than returning a null value. As a result, this make impossible to represent correctly One-to-One relationship. Take this example, using the "School Database" available here: https://learn.microsoft.com/en-us/ef/ef6/resources/school-database

There is a one-to-one relationship between Course and OnlineCourse as OnlineCourse is a "specialization" of Course. Same goes between Course and OnsiteCourse and This is the following DAB config:

{
  "$schema": "https://github.com/Azure/data-api-builder/releases/download/v0.8.52/dab.draft.schema.json",
  "data-source": {
    "database-type": "mssql",
    "connection-string": "@env('MSSQL')",
    "options": {
      "set-session-context": false
    }
  },
  "runtime": {
    "rest": {
      "enabled": true,
      "path": "/api"
    },
    "graphql": {
      "enabled": true,
      "path": "/graphql",
      "allow-introspection": true
    },
    "host": {
      "cors": {
        "origins": [],
        "allow-credentials": false
      },
      "authentication": {
        "provider": "StaticWebApps"
      },
      "mode": "development"
    }
  },
  "entities": {
    "Course": {
      "source": {
        "object": "dbo.Course",
        "type": "table"
      },
      "graphql": {
        "enabled": true,
        "type": {
          "singular": "Course",
          "plural": "Courses"
        }
      },
      "rest": {
        "path": "/courses",
        "enabled": true
      },
      "permissions": [
        {
          "role": "anonymous",
          "actions": [
            {
              "action": "*"
            }
          ]
        }
      ],
      "relationships": {
        "OnlineCourse": {
          "cardinality": "one",
          "target.entity": "OnlineCourse"
        },
        "OnsiteCourse": {
          "cardinality": "one",
          "target.entity": "OnsiteCourse"
        }
      }
    },
    "OnlineCourse": {
      "source": {
        "object": "dbo.OnlineCourse",
        "type": "table"
      },
      "graphql": {
        "enabled": true,
        "type": {
          "singular": "OnlineCourse",
          "plural": "OnlineCourses"
        }
      },
      "rest": {
        "path": "/online-courses",
        "enabled": true
      },
      "permissions": [
        {
          "role": "anonymous",
          "actions": [
            {
              "action": "*"
            }
          ]
        }
      ],
      "relationships": {
        "Course": {
          "cardinality": "one",
          "target.entity": "Course"
        }
      }
    },
    "OnsiteCourse": {
      "source": {
        "object": "dbo.OnsiteCourse",
        "type": "table"
      },
      "graphql": {
        "enabled": true,
        "type": {
          "singular": "OnsiteCourse",
          "plural": "OnsiteCourses"
        }
      },
      "rest": {
        "path": "/onsite-courses",
        "enabled": true
      },
      "permissions": [
        {
          "role": "anonymous",
          "actions": [
            {
              "action": "*"
            }
          ]
        }
      ],
      "relationships": {
        "Course": {
          "cardinality": "one",
          "target.entity": "Course"
        }
      }
    }
  }
}

if I run the following GraphQL query:

query {
  courses {
    items {
      Title
      OnlineCourse {   
          URL
      }
      OnsiteCourse {
          Location
          Days
      }
    }
  }
}

I get the following error:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field.",
      "locations": [
        {
          "line": 5,
          "column": 7
        }
      ],
      "path": [
        "courses",
        "items",
        0,
        "OnlineCourse"
      ],
      "extensions": {
        "code": "HC0018"
      }
    }
  ]
}

As for not all courses the field returned by the referenced entities will be available.

Version

Microsoft.DataApiBuilder 0.8.52+c69925060e1942d28515b9c4b89ea24832da0c7c

What database are you using?

Azure SQL

What hosting model are you using?

Local (including CLI)

Which API approach are you accessing DAB through?

GraphQL

Relevant log output

Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'Hot Chocolate GraphQL Pipeline'
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
      1c429351-7b86-4eb2-9298-2e56e41dafe9: Request authentication state: Anonymous.
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
      1c429351-7b86-4eb2-9298-2e56e41dafe9: The request will be executed in the context of Anonymous role
dbug: Azure.DataApiBuilder.Core.Resolvers.IQueryExecutor[0]
      1c429351-7b86-4eb2-9298-2e56e41dafe9: Executing query:
SELECT TOP 100 [table0].[Title] AS [Title], JSON_QUERY ([table1_subq].[data]) AS [OnlineCourse], JSON_QUERY ([table3_subq].[data]) AS [OnsiteCourse] FROM [dbo].[Course] AS [table0] OUTER APPLY (SELECT TOP 1 [table1].[URL] AS [URL] FROM [dbo].[OnlineCourse] AS [table1] WHERE [table1].[CourseID] = [table0].[CourseID] ORDER BY [table1].[CourseID] ASC FOR JSON PATH, INCLUDE_NULL_VALUES,WITHOUT_ARRAY_WRAPPER) AS [table1_subq]([data]) OUTER APPLY (SELECT TOP 1 [table3].[Location] AS [Location], [table3].[Days] AS [Days] FROM [dbo].[OnsiteCourse] AS [table3] WHERE [table3].[CourseID] = [table0].[CourseID] ORDER BY [table3].[CourseID] ASC FOR JSON PATH, INCLUDE_NULL_VALUES,WITHOUT_ARRAY_WRAPPER) AS [table3_subq]([data]) WHERE 1 = 1 ORDER BY [table0].[CourseID] ASC FOR JSON PATH, INCLUDE_NULL_VALUES
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'Hot Chocolate GraphQL Pipeline'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/2 POST https://localhost:5001/graphql application/json 212 - 500 - application/json;+charset=utf-8 5.6927ms

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggraphqltriageissues to be triaged

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions