Relations FAQ

    Sometimes you want to have in your object id of the related object without loading it.For example:

    1. @Entity()
    2. export class Profile {
    3. @PrimaryGeneratedColumn()
    4. id: number;
    5. @Column()
    6. gender: string;
    7. @Column()
    8. photo: string;
    9. }
    1. import {Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn} from "typeorm";
    2. import {Profile} from "./Profile";
    3. @Entity()
    4. export class User {
    5. @PrimaryGeneratedColumn()
    6. id: number;
    7. @Column()
    8. name: string;
    9. @OneToOne(type => Profile)
    10. @JoinColumn()
    11. profile: Profile;
    12. }

    When you load a user without profile joined you won’t have any information about profile in your user object,even profile id:

    But sometimes you want to know what is the “profile id” of this user without loading the whole profile for this user.To do this you just need to add another property to your entity with @Columnnamed exactly as the column created by your relation. Example:

    1. import {Profile} from "./Profile";
    2. @Entity()
    3. export class User {
    4. @PrimaryGeneratedColumn()
    5. id: number;
    6. @Column()
    7. name: string;
    8. @Column({ nullable: true })
    9. profileId: number;
    10. @OneToOne(type => Profile)
    11. @JoinColumn()
    12. profile: Profile;
    13. }

    That’s all. Next time you load a user object it will contain a profile id:

    1. User {
    2. id: 1,
    3. name: "Umed",
    4. }

    Alternative and more flexible way is to use QueryBuilder:

    1. const user = await connection
    2. .getRepository(User)
    3. .createQueryBuilder("user")
    4. .leftJoinAndSelect("user.profile", "profile")
    5. .leftJoinAndSelect("user.photos", "photo")
    6. .leftJoinAndSelect("user.videos", "video")

    Using QueryBuilder you can do innerJoinAndSelect instead of leftJoinAndSelect(to learn the difference between LEFT JOIN and INNER JOIN refer to your SQL documentation),you can join relation data by a condition, make ordering, etc.

    Learn more about QueryBuilder.

    Sometimes it is useful to initialize your relation properties, for example:

    1. import {Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable} from "typeorm";
    2. import {Category} from "./Category";
    3. @Entity()
    4. export class Question {
    5. @PrimaryGeneratedColumn()
    6. id: number;
    7. @Column()
    8. title: string;
    9. @Column()
    10. text: string;
    11. @ManyToMany(type => Category, category => category.questions)
    12. @JoinTable()
    13. categories: Category[] = []; // see = [] initialization here
    14. }

    Now when you save this object categories inside it won’t be touched - because it is unset.

    But if you have initializer, the loaded object will look like as follow:

    1. Question {
    2. id: 1,
    3. title: "Question about ...",
    4. }

    When you save the object it will check if there are any categories in the database bind to the question -and it will detach all of them. Why? Because relation equal to [] or any items inside it will be consideredlike something was removed from it, there is no other way to check if an object was removed from entity or not.

    Therefore, saving an object like this will bring you problems - it will remove all previously set categories.