neo4j / graphql

A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations.
https://neo4j.com/docs/graphql-manual/current/
Apache License 2.0
507 stars 149 forks source link

Duplicate Nodes Created with Nested 'Connect' when using Interfaces #832

Closed jnterry closed 2 years ago

jnterry commented 2 years ago

Describe the bug When using the autogenerated create mutations, with connect on nested relationship fields - if the type the relationship refers to is an interface rather than type, and you are attempting to create multiple nodes in a single call, spurious duplicate nodes are created.

Type definitions

Note: This is the same schema that generates another (I think unrelated) bug: https://github.com/neo4j/graphql/issues/847

interface Entity {
    id: String!
}

type Person implements Entity {
    id   : String! @unique
    name : String!
}

type Place implements Entity {
    id       : String! @unique
    location : Point!
}

type Interaction  {
    id       : ID! @id
    kind     : String!
    subjects : [Entity!]! @relationship(type: "ACTED_IN", direction: IN )
    objects  : [Entity!]! @relationship(type: "ACTED_IN", direction: OUT)
}

To Reproduce

Run the following mutation against the graphql API using an empty neo4j database:

mutation {
  createPeople(input: [
    { id: "adam", name: "Adam" },
    { id: "eve",  name: "Eve" },
    { id: "cain", name: "Cain"},
    { id: "abel", name: "Abel" }, 
  ]) {
    people {
      id
    }
  }
  createInteractions(input: [{
    subjects : { connect: { where: { node: { id_IN: ["adam", "eve"] }}}},
    kind     : "PARENT_OF",
    objects  : { connect: { where: { node: { id_IN: ["cain"] }}}}
  },{
    subjects : { connect: { where: { node: { id_IN: ["adam", "eve"] }}}},
    kind     : "PARENT_OF",
    objects  : { connect: { where: { node: { id_IN: ["abel"] }}}}
  }]) {
    info { nodesCreated }
    interactions { id }
  }
}

Expected behavior

createInteractions should create exactly 2 nodes - instead it creates 3 nodes.

The output createInterations.interactions list contains just 2 ID strings - however info.nodesCreated is set to 3 - and examining the graph shows indeed that an extra node has been incorrectly created.

Note that if the two nodes are created with 2 separate calls to createInteractions (with an input array of length 1 in both cases), the correct behavior is observed. Additionally, modifying the type definitions on the subjects and objects relationship fields to be Person rather than Entity results in the correct behavior. Neither of these workarounds should be required.

Screenshots

Incorrect resultant graph structure from above mutation: image

Expected Graph Structure: image

System (please complete the following information):

neo4j-team-graphql commented 2 years ago

Many thanks for raising this bug report @jnterry. :bug: We will now attempt to reproduce the bug based on the steps you have provided.

Please ensure that you've provided the necessary information for a minimal reproduction, including but not limited to:

Thanks again! :pray:

neo4j-team-graphql commented 2 years ago

We've been able to confirm this bug using the steps to reproduce that you provided - many thanks @jnterry! :pray: We will now prioritise the bug and address it appropriately.

darrellwarde commented 2 years ago

This is going to be pretty important for us to fix but we want to make sure we do it right. So we're going to plan out the fix for this as we would a feature - it could get pretty complex pretty quickly.

angrykoala commented 2 years ago

Confirmed that this is still a problem in 3.6.0