Home > Enterprise >  Spring GraphQL mutation NullPointerException
Spring GraphQL mutation NullPointerException

Time:07-27

I'm learning GraphQL in spring boot and I have created a mutation that saves used details in database. When I try to call the mutation from GraphiQL UI using following mutation query, it throws NullPointerException because the object I passed in mutation is not mapped with UserDto and I don't know why.

I have following code:

Controller

@Controller
public class UserController {

    private UserService userService;


    public UserController(UserService userService) {
        this.userService = userService;
    }

    @QueryMapping(name = "userById")
    public UserDto findUserById(@Argument Long id) {
        return userService.findById(id);
    }

    @QueryMapping
    public String removeUserById(@Argument Long id) {
        return userService.removeById(id);
    }

    @MutationMapping(name = "save")
    public UserDto save(@Argument UserDto user) {
        return  userService.save(user);
    }

    @QueryMapping(name = "users")
    public List<UserDto> findAll() {
        return userService.findAll();
    }

}

GraphQL Schema

schema {
    query: Query
    mutation: Mutation
}


type Query{
    users:[User]
    userById(id:ID):User
}
type Mutation{
    save(userInput:UserInput):User
}

#input types
input UserInput{
    firstName:String!
    lastName:String!
    emailAddress:String!
    ipAddress:String!
    address:AddressInput!
}
input AddressInput{
    addressLine1:String!
    addressLine2:String!
    addressLine3:String!
    addressLine4:String!
    addressLine5:String!
    addressPostCode:Int!
}

#object types
type User{
    firstName:String!
    lastName:String!
    emailAddress:String!
    ipAddress:String!
    address:Address!
}
type Address{
    addressLine1:String!
    addressLine2:String!
    addressLine3:String!
    addressLine4:String!
    addressLine5:String!
    addressPostCode:Int!
}

Mutation Query

mutation Save($userDto: UserInput!) {
  save(userInput: $userDto) {
    firstName
    lastName
    emailAddress
    ipAddress
    address {
      addressLine1
      addressLine2
      addressLine3
      addressLine4
      addressLine5
      addressPostCode
    }
  }
}

Variables

{
  "userDto": {
    "ipAddress": "192.168.0.124",
    "firstName": "John",
    "lastName": "Mark",
    "emailAddress": "[email protected]",
    "address": {
      "addressLine1": "251 WC",
      "addressLine2": "UC MAIN",
      "addressLine3": "PB121",
      "addressLine4": "New York",
      "addressLine5": "USA",
      "addressPostCode": 457821
    }
  }
}

Results

{
  "errors": [
    {
      "message": "INTERNAL_ERROR for b6287602-fc10-6ecf-2091-b57ceaeb9f0a",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "save"
      ],
      "extensions": {
        "classification": "INTERNAL_ERROR"
      }
    }
  ],
  "data": {
    "save": null
  }
}

When I run the GraphQL query, it throws NullPointerException in console.

Console Error

java.lang.NullPointerException: Cannot invoke "com.graphql.sample.dto.UserDto.getEmailAddress()" because "userDto" is null

CodePudding user response:

type User{
    firstName:String!
    lastName:String!
    emailAddress:String!
    ipAddress:String!
    address:Address!
}

Reason 1: Your save mutation result is returned to this entity. But it can be possible that a property that you are receiving might be null that's why this error is thrown, as you are using ! with each property. You can remove ! if a value can/is null

Reason 2: I couldn't see your resolver so it might be possible that the result is not an object or the property names that you are receiving don't match with the property names inside type User. It should be same or use resolver to provide their values

CodePudding user response:

I'm answering my question because I have already solved it. I had made a small mistake in controller near @Argument UserDto user as below:

@MutationMapping(name = "save")
public UserDto save(@Argument(name = "userInput") UserDto user) {
        return  userService.save(user);
}

The name in @Argument should match the name of parameter in Mutation type as below:

type Mutation{
    save(userInput:UserInput):User
}
  • Related