Skip to content

Multiple FK to same entity cause issue with an unnamed relation and values not returned #2757

Description

@bvkimball

I am moderately confident, i am not doing something wrong.

Description and expected behavior
Prior on Zenstack V2:
prisma required relations to have names in n+ scenario but 1 relation could remain unnamed. This is allowed even though not recommended.

After upgrading to V3:
When two relations connect the same pair of models and only one of the two relation pairs carries a @relation("name"), the unnamed pair resolves to the wrong opposite field. In the generated schema, the unnamed field's relation.opposite points at the named relation's foreign key, so relation filters (some/none/every) and nested reads traverse the wrong column and silently return incorrect results (no error, types still compile). Prisma resolves this schema correctly; ZenStack v3 does not.

Example

datasource db {
  provider = 'postgresql'
  url      = env('DATABASE_URL')
}

model Category {
  id       String    @id @default(cuid())
  products Product[]                       // unnamed — opposite SHOULD be Product.category
  featured Product[] @relation("Featured")
}

model Product {
  id           String    @id @default(cuid())
  category     Category  @relation(fields: [categoryId], references: [id])
  categoryId   String
  featuredIn   Category? @relation("Featured", fields: [featuredInId], references: [id])
  featuredInId String?
}

Expected: Category.products ↔ Product.category (categoryId); Category.featured ↔ Product.featuredIn (featuredInId).

Actual: generated schema gives Category.products.relation.opposite = "featuredIn" (should be "category") — both products and featured resolve to featuredIn.

Observable symptom:

await db.category.findMany({ where: { products: { none: {} } } });

compiles to the wrong join column:

where not exists (
  select 1 from "Product"
  where "Category"."id" = "Product"."featuredInId"   -- ❌ should be "Product"."categoryId"
)

Workaround: name both relation pairs (@relation("CategoryProducts") on products/category, plus the existing "Featured").

I also found an that field ordering change how field was resolved.

Another reason why this is an issue is because I use relation fields in my BaseEntity and extend, those cant really be named...

Environment (please complete the following information):

  • ZenStack version: 3.7.* cant test on 3.8.*
  • Database type: Postgresql
  • Node.js/Bun version: 24
  • Package manager: yarn

Additional context
Sounded like this would fix
fix(cli): add missing opposite relation fields during db pull when multiple FKs target the same model (https://github.com/zenstackhq/zenstack/pull/2652[)](https://github.com/zenstackhq/zenstack/commit/e492c937ddb07411531dabd3ca9182ec2be53b3a)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions