Bird
Raised Fist0
NestJSframework~5 mins

Relations (OneToMany, ManyToOne, ManyToMany) in NestJS

Choose your learning style10 modes available
Introduction

Relations help connect data between tables so you can organize and access related information easily.

When you want to link users to their posts in a blog app.
When you need to connect orders to customers in a shopping system.
When you want to track which students are in which classes.
When you want to manage tags that can belong to many articles.
When you want to keep track of comments related to a specific post.
Syntax
NestJS
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, ManyToMany, JoinTable } 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)
  parent: ParentEntity;
}

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

  @ManyToMany(() => EntityB)
  @JoinTable()
  relatedEntities: EntityB[];
}

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

@OneToMany and @ManyToOne always work together to link two entities.

@ManyToMany needs a @JoinTable on one side to create the connection table.

Examples
This example shows authors having many books, and each book belongs to one author.
NestJS
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from 'typeorm';

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

  @OneToMany(() => Book, book => book.author)
  books: Book[];
}

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

  @ManyToOne(() => Author, author => author.books)
  author: Author;
}
This example shows students and courses connected many-to-many, meaning students can join many courses and courses can have many students.
NestJS
import { Entity, PrimaryGeneratedColumn, ManyToMany, JoinTable } from 'typeorm';

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

  @ManyToMany(() => Course)
  @JoinTable()
  courses: Course[];
}

@Entity()
export class Course {
  @PrimaryGeneratedColumn()
  id: number;
}
Sample Program

This program defines three entities: User, Post, and Tag. Users can have many posts (OneToMany). Each post belongs to one user (ManyToOne). Posts can have many tags and tags can belong to many posts (ManyToMany).

NestJS
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, ManyToMany, JoinTable } from 'typeorm';

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

  @Column()
  name: string;

  @OneToMany(() => Post, post => post.user)
  posts: Post[];
}

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

  @Column()
  title: string;

  @ManyToOne(() => User, user => user.posts)
  user: User;

  @ManyToMany(() => Tag)
  @JoinTable()
  tags: Tag[];
}

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

  @Column()
  name: string;
}
OutputSuccess
Important Notes

Always define both sides of OneToMany and ManyToOne relations for proper data access.

Use @JoinTable only on one side of ManyToMany to avoid errors.

Relations help keep your data organized and easy to query.

Summary

Relations connect different data tables to show how they relate.

OneToMany and ManyToOne link one item to many others and back.

ManyToMany connects many items on both sides with a join table.

Practice

(1/5)
1. In NestJS using TypeORM, which decorator correctly defines a OneToMany relationship from an Author entity to a Book entity?
easy
A. @OneToMany(() => Book, book => book.author)
B. @ManyToOne(() => Book, book => book.author)
C. @ManyToMany(() => Book, book => book.author)
D. @OneToOne(() => Book, book => book.author)

Solution

  1. Step 1: Understand the relationship direction

    A OneToMany relationship means one Author has many Books.
  2. Step 2: Identify the correct decorator syntax

    The decorator @OneToMany(() => Book, book => book.author) correctly sets this relation from Author to Book.
  3. Final Answer:

    @OneToMany(() => Book, book => book.author) -> Option A
  4. Quick Check:

    OneToMany from Author to Book = @OneToMany [OK]
Hint: OneToMany decorator links one entity to many others [OK]
Common Mistakes:
  • Confusing OneToMany with ManyToOne
  • Using ManyToMany instead of OneToMany
  • Incorrect arrow function syntax in decorator
2. Which of the following is the correct syntax to define a ManyToOne relation in a NestJS entity?
easy
A. @OneToOne(type => User, user => user.posts)
B. @OneToMany(type => User, user => user.posts)
C. @ManyToOne(type => User, user => user.posts)
D. @ManyToMany(type => User, user => user.posts)

Solution

  1. Step 1: Recognize the relation type

    ManyToOne means many posts belong to one user.
  2. Step 2: Confirm correct decorator syntax

    @ManyToOne(type => User, user => user.posts) is the correct way to define this relation.
  3. Final Answer:

    @ManyToOne(type => User, user => user.posts) -> Option C
  4. Quick Check:

    ManyToOne relation uses @ManyToOne decorator [OK]
Hint: ManyToOne decorator links many items to one parent [OK]
Common Mistakes:
  • Using OneToMany instead of ManyToOne
  • Wrong arrow function parameter name
  • Missing inverse side property
3. Given these entity relations in NestJS with TypeORM:
class Student {
  @ManyToMany(() => Course, course => course.students)
  courses: Course[];
}

class Course {
  @ManyToMany(() => Student, student => student.courses)
  @JoinTable()
  students: Student[];
}

What will be the result of fetching a Course with its students included?
medium
A. A Course object with a single Student object in the 'students' property
B. A Course object with an array of Student objects in the 'students' property
C. A Course object without any students because @JoinTable is missing
D. An error because ManyToMany requires OneToMany on one side

Solution

  1. Step 1: Understand ManyToMany relation with JoinTable

    ManyToMany with @JoinTable on one side creates a join table linking many students to many courses.
  2. Step 2: Fetching Course includes students array

    Fetching a Course with relations loaded returns a Course object with an array of Student objects in 'students'.
  3. Final Answer:

    A Course object with an array of Student objects in the 'students' property -> Option B
  4. Quick Check:

    ManyToMany with @JoinTable returns array of related entities [OK]
Hint: ManyToMany with @JoinTable returns arrays on both sides [OK]
Common Mistakes:
  • Expecting single object instead of array
  • Forgetting @JoinTable on one side
  • Confusing ManyToMany with OneToMany
4. Consider this NestJS entity code snippet:
@Entity()
class Post {
  @OneToMany(() => Comment, comment => comment.post)
  comments: Comment[];
}

@Entity()
class Comment {
  @ManyToOne(() => Post, post => post.comments)
  post: Post;
}

What is wrong if the comments property in Post is not initialized as an array?
medium
A. No issue; undefined is acceptable for relations
B. TypeORM will automatically initialize it as an empty array
C. The database schema will not be created
D. It will cause runtime errors when accessing or pushing comments

Solution

  1. Step 1: Recognize relation property type

    comments is an array of Comment entities, so it should be initialized to avoid undefined.
  2. Step 2: Understand runtime behavior

    If not initialized, accessing or pushing to comments causes runtime errors like 'cannot read property push of undefined'.
  3. Final Answer:

    It will cause runtime errors when accessing or pushing comments -> Option D
  4. Quick Check:

    Uninitialized array relation causes runtime errors [OK]
Hint: Always initialize OneToMany arrays to avoid runtime errors [OK]
Common Mistakes:
  • Assuming TypeORM auto-initializes arrays
  • Ignoring runtime errors from undefined arrays
  • Confusing property initialization with database schema
5. You want to model a social media app where users can follow many other users and be followed by many users. Which NestJS TypeORM relation setup correctly models this ManyToMany self-referencing relation?
hard
A.
@Entity()
class User {
  @ManyToMany(() => User, user => user.followers)
  @JoinTable()
  following: User[];

  @ManyToMany(() => User, user => user.following)
  followers: User[];
}
B.
@Entity()
class User {
  @OneToMany(() => User, user => user.followers)
  following: User[];

  @ManyToOne(() => User, user => user.following)
  followers: User[];
}
C.
@Entity()
class User {
  @ManyToOne(() => User, user => user.followers)
  following: User[];

  @OneToMany(() => User, user => user.following)
  followers: User[];
}
D.
@Entity()
class User {
  @ManyToMany(() => User)
  @JoinTable()
  following: User[];

  @ManyToMany(() => User)
  followers: User[];
}

Solution

  1. Step 1: Understand self-referencing ManyToMany

    Users follow many users and are followed by many users, so a ManyToMany self-relation is needed.
  2. Step 2: Correctly set inverse sides and JoinTable

    @Entity()
    class User {
      @ManyToMany(() => User, user => user.followers)
      @JoinTable()
      following: User[];
    
      @ManyToMany(() => User, user => user.following)
      followers: User[];
    }
    uses @ManyToMany with inverse sides and @JoinTable on one side, correctly modeling the relation.
  3. Final Answer:

    Code snippet with @ManyToMany, inverse sides, and @JoinTable -> Option A
  4. Quick Check:

    Self-referencing ManyToMany needs inverse sides and one @JoinTable [OK]
Hint: Self ManyToMany needs inverse sides and one @JoinTable [OK]
Common Mistakes:
  • Using OneToMany or ManyToOne for many-to-many
  • Missing inverse side property
  • Missing @JoinTable on one side
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard