Logo

dev-resources.site

for different kinds of informations.

TypeORM - remove children with orphanedRowAction

Published at
11/6/2023
Categories
typeorm
javascript
node
database
Author
mgohin
Categories
4 categories in total
typeorm
open
javascript
open
node
open
database
open
Author
6 person written this
mgohin
open
TypeORM - remove children with orphanedRowAction

TypeORM is a very convenient ORM for JS apps. We use it with NestJS and running it on NodeJS.

But we are not here to talk about our technical stack, but to deep dive, directly into relations with TypeORM.

When you are referencing children entities from a parent entity, you use a @OneToMany relation and a @ManyToOne relation.

import {Entity, Column, ManyToOne, OneToMany, PrimaryGeneratedColumn} from "typeorm";

@Entity()
export class ParentEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @OneToMany(
    () => ChildEntity,
    child => child.parent
  )
  children: ChildEntity[];
}

@Entity()
export class ChildEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToOne(
    () => ParentEntity,
    parent => parent.children,
    {nullable: false}
  )
  parent: ParentEntity;
}
Enter fullscreen mode Exit fullscreen mode

And the best part referencing children entities in the parent entity, is that you can manipulate children to add, remove or update them.
If you add {cascade: true}, every change in children will be saved when you save the parent.

Let's update the parent entity :

@Entity()
export class ParentEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @OneToMany(
    () => ChildEntity,
    child => child.parent,
    {cascade: true}
  )
  children: ChildEntity[];

  removeChild(childId: number): void {
    // lets remove the target from the array
    this.children = this.children.filter(child => child.id !== childId);
  }
}

export class MyService() {

  private parentEntity: ParentEntity;

  constructor(private readonly parentRepository: Repository<ParentEntity>) {}

  removeChildFromParent(childId: number) {
    this.parent.removeChild(childId);
    this.parentRepository.save(this.parent);
  }
}
Enter fullscreen mode Exit fullscreen mode

And now we are in troubles because this line this.parentRepository.save(this.parent); will throw an error, because the default behaviour when you remove an entity from the array, is to set its property parent: ParentEntity; to null and so the column in database called parent_id which is not nullable 😨😱

How the hell are we gonna do ?

Nothing, end of thread, see ya.

Come back my friends, we have a solution, and it's not well documented yet in the TypeORM doc :)

It's the magical option orphanedRowAction that will save us, but its default value that is causing our troubles : nullify.

orphanedRowAction: "nullify" | "delete" | "soft-delete" | disable - When a parent is saved (cascading enabled) without a child/children that still exists in database, this will control what shall happen to them.

All you have to do is to use it in the child entity relation to its parent (that the unclear point in TypeORM's doc to me) :

@Entity()
export class ChildEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToOne(
    () => ParentEntity,
      parent => parent.children,
    {
      nullable: false,
      orphanedRowAction: "delete"
    }
  )
  parent: ParentEntity;
}
Enter fullscreen mode Exit fullscreen mode

So now when you remove an entity from the parent's children array, there'll be a DELETE query to remove it from database.

And now, your mind is free.

typeorm Article's
30 articles in total
Favicon
Creating Typescript app with decorator-based dependency injection 💉
Favicon
ORM and Migrating/Adding Data to MySql Database from MongoDb using TypeOrm in javaScript
Favicon
🌟 NestJS + Databases: Making Snake Case Seamless!🐍
Favicon
NestJS TypeORM and Multi-Tenancy
Favicon
Nx + TypeORM + NestJS + Migrations
Favicon
Handling TypeORM migrations in Electron apps
Favicon
How to manage multiple environments with dotenv and Databases config in NestJS
Favicon
Sveltekit + TypeScript + TypeORM + ESM
Favicon
Using TypeORM with TSX: A Smoother Development Experience
Favicon
Prisma or TypeORM ?
Favicon
Mock TypeORM Package
Favicon
Connecting a Serverless PostgreSQL Database (Neon) to NestJS Using the Config Service
Favicon
NestJS and TypeORM — Efficient Schema-Level Multi-Tenancy with Auto Generated Migrations: A DX Approach
Favicon
Getting Started with NestJS and TypeORM: A Beginner's Guide
Favicon
Migration - Module query with TypeORM version 0.3.x
Favicon
Double bind the foreign key to avoid unnecessary JOIN in TypeORM
Favicon
Handling Migrations on NestJS with TypeORM
Favicon
match all conditions in the first array and at least one condition for the second array typeorm
Favicon
Taming cross-service database transactions in NestJS with AsyncLocalStorage
Favicon
Announcing Version 2.0 of nestjs-DbValidator
Favicon
Optimizing SQL Queries by 23x!!!
Favicon
Building my own PostgresGUI with TypeORM+TypeGraphQl class generaion
Favicon
TypeORM | Query Builder
Favicon
NestJs에서 TypeORM을 사용하여 MySQL 연동, 2024-01-25
Favicon
Defining Custom Many-to-many Relationship in NestJS TypeORM.
Favicon
4. Building an Abstract Repository
Favicon
3. Building a Common Repository for Nest.js Microservices
Favicon
TypeORM - remove children with orphanedRowAction
Favicon
Migrating NestJS project with TypeORM to Prisma
Favicon
Authentication part 2 using NestJS

Featured ones: