Skip to content

Error in Autogenerated Resolver for Many-to-Many Relations #464

@naccio8

Description

@naccio8

Issue Description

There seems to be a bug in the generation of automatic resolvers for many-to-many relationships.

Details:

  • I haven't verified if this issue is specific to MongoDB or if it also occurs with relational databases.
  • The problem arises specifically with many-to-many relationships. One-to-many relationships work fine.

Example:

Given the following schema:

model Ready {
  id                String                  @id @map("_id")
  destinazioneId    String?
  destinazione      Standstills?            @relation("ReadyToDestinazione", fields: [destinazioneId], references: [id])
  intermedi         ReadyIntermedi[]        @relation("ReadyToIntermedi")
  partenzaId        String
  partenza          Standstills?            @relation("ReadyToPartenza", fields: [partenzaId], references: [id])
}

model Standstills {
  id                      String                    @id @map("_id")
  indirizzo               String
  readyPartenza           Ready[]                   @relation("ReadyToPartenza")
  readyDestinazione       Ready[]                   @relation("ReadyToDestinazione")
  readyIntermediStandstill ReadyIntermedi[]         @relation("IntermediToStandstill")
}

model ReadyIntermedi {
  id            String      @id @map("_id")
  readyId       String
  ready         Ready       @relation("ReadyToIntermedi", fields: [readyId], references: [id])
  standstillId  String
  standstill    Standstills @relation("IntermediToStandstill", fields: [standstillId], references: [id])
  order         Int         // To maintain the order of intermediaries

  @@unique([readyId, standstillId])
}

If I query:

query Readies($take: Int) {
  readies(take: $take) {
    id
    partenza {
      indirizzo
    }
    intermedi {
      order
      readyId
      standstillId
    }
  }
}

It works fine with the correct relation on partenza.

However, if I modify the query and add:

standstill {
    indirizzo
  }

at intermedi and obtain this query:

query Readies($take: Int) {
  readies(take: $take) {
    id
    partenza {
      indirizzo
    }
    intermedi {
      order
      readyId
      standstillId
      standstill {
        indirizzo
      }
    }
  }
}

I get the following error:

"code": "INTERNAL_SERVER_ERROR",
"stacktrace": [
  "NotFoundError: No ReadyIntermedi found",
]

Analysis

In the generated TypeScript resolvers, I found:

@TypeGraphQL.Resolver(_of => ReadyIntermedi)
export class ReadyIntermediRelationsResolver {
  @TypeGraphQL.FieldResolver(_type => Ready, {
    nullable: false
  })
  async ready(@TypeGraphQL.Root() readyIntermedi: ReadyIntermedi, @TypeGraphQL.Ctx() ctx: any, @TypeGraphQL.Info() info: GraphQLResolveInfo): Promise<Ready> {
    const { _count } = transformInfoIntoPrismaArgs(info);
    return getPrismaFromContext(ctx).readyIntermedi.findUniqueOrThrow({
      where: {
        id: readyIntermedi.id,
      },
    }).ready({
      ...(_count && transformCountFieldIntoSelectRelationsCount(_count)),
    });
  }

  @TypeGraphQL.FieldResolver(_type => Standstills, {
    nullable: false
  })
  async standstill(@TypeGraphQL.Root() readyIntermedi: ReadyIntermedi, @TypeGraphQL.Ctx() ctx: any, @TypeGraphQL.Info() info: GraphQLResolveInfo): Promise<Standstills> {
    const { _count } = transformInfoIntoPrismaArgs(info);
    return getPrismaFromContext(ctx).readyIntermedi.findUniqueOrThrow({
      where: {
        id: readyIntermedi.id,
      },
    }).standstill({
      ...(_count && transformCountFieldIntoSelectRelationsCount(_count)),
    });
  }
}

This is incorrect. The correct resolvers should be:

@TypeGraphQL.Resolver(_of => ReadyIntermedi)
export class ReadyIntermediRelationsResolver {
  @TypeGraphQL.FieldResolver(_type => Ready, {
    nullable: false
  })
  async ready(
    @TypeGraphQL.Root() readyIntermedi: ReadyIntermedi, 
    @TypeGraphQL.Ctx() ctx: any, 
    @TypeGraphQL.Info() info: GraphQLResolveInfo
  ): Promise<Ready> {
    const { _count } = transformInfoIntoPrismaArgs(info);
    return getPrismaFromContext(ctx).ready.findUniqueOrThrow({
      where: {
        id: readyIntermedi.readyId,  // Correct access via readyId
      },
      ...(_count && transformCountFieldIntoSelectRelationsCount(_count)),
    });
  }

  @TypeGraphQL.FieldResolver(_type => Standstills, {
    nullable: false
  })
  async standstill(
    @TypeGraphQL.Root() readyIntermedi: ReadyIntermedi, 
    @TypeGraphQL.Ctx() ctx: any, 
    @TypeGraphQL.Info() info: GraphQLResolveInfo
  ): Promise<Standstills> {
    const { _count } = transformInfoIntoPrismaArgs(info);
    return getPrismaFromContext(ctx).standstills.findUniqueOrThrow({
      where: {
        id: readyIntermedi.standstillId,  // Correct access via standstillId
      },
      ...(_count && transformCountFieldIntoSelectRelationsCount(_count)),
    });
  }
}

Environment & setup

  • OS: Windows
  • Database: MongoDB v7.0.9
  • Node.js version: v20.10.0

Prisma Version

{
"dependencies": {
    "@prisma/client": "^5.18.0",
  },
  "devDependencies": {
    "@types/node": "^20.12.10",
    "prisma": "^5.18.0",
    "typegraphql-prisma": "^0.28.0",
    "typescript": "^5.4.5"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcommunitySomething initiated by the community

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions