Search code examples
sqlsql-servertypescriptormtypeorm

TypeORM cannot delete row with ManyToOne / OneToMany relation


I have this problem right now that I don't know how to fix honestly. I spent hours on this already and cannot find the solution. I am using MS-SQL on Azure.

The way I have set up my entities is the following:

  • Customer and Visits: OneToMany (Primary)
  • Visits and Customers: ManyToOne (Inverse)

I am soft-deleting my customers, so that the information for the visits can be retrieved regardless of whether or not the user wants to see the customer data specifically. The data is still getting resolved correctly using the relationship. That's also why I don't want to use "Cascade DELETE" here.

However, since I want to delete visits completely (not soft-deleting like the customers) I am facing issues probably regarding foreign key constraints (not sure, because I don't get any error output from TypeORM). The DeleteResult.affected property however returns 0, which is what I see in my DataGrip queries as well, where I check the actual table data.

Whats important as well is that I am able to manually delete the row using a simple SQL statement like the following:

DELETE FROM visits
WHERE uuid = 'f0ea300d-...-656a'

My entities are set up like this (left unimportant information out):

@Entity({ name: 'customers' })
export class Customer {

  @PrimaryColumn()
  uuid: string

  @OneToMany(() => Visit, (visit) => visit.customer)
  visits?: Visit[]
}
@Entity({ name: 'visits' })
export class Visit {

  @PrimaryColumn()
  uuid: string

  @ManyToOne(() => Customer, (customer) => customer.visits)
  customer: Customer
}

My GraphQL resolver:

@Mutation(() => Boolean)
async deleteVisitsByUuid(
  @Arg('uuid') uuid: string,
  @Ctx() { conn }: AppContext,
): Promise<boolean> {
  const repo = conn.getRepository(Customer)
  const result = await repo.delete(uuid)
  const affected = result.affected

  if (affected === undefined || affected == null) {
    return false
  } else {
    return affected > 0
  }
}

Solution

  • The problem was conn.getRepository(Customer). I have replaced it with conn.getRepository(Visit).