Search code examples
node.jstypescriptpostgresqltypeorm

TypeORM insert row with foreign key


I have a @OneToMany relation between
Chatroom < 1 ---- M > Messages
And the problem that I have is, whenever I try to insert a Message (or bulk of Messages), The foreign key for ChatRoom is null.
In addition, I'm uploading my setup.

@Entity("messages")
export class Message {

    @PrimaryColumn()
    id: string;

    @ManyToOne(() => ChatRoom, chatroom => chatroom.messages)
    chatRoom: ChatRoom | undefined

    @Column({nullable: false})
    message: string;

    @Column({nullable: false})
    receiver: string;

    @Column({nullable: false})
    created_utc: Date;
}
@Entity("chatrooms")
export class ChatRoom {

    @PrimaryColumn()
    id: string;

    @OneToMany(() => Message, message => message.chatRoom, {
        cascade: ["insert", "remove"]
    })
    @JoinColumn({name: 'id'})
    messages: Message[];

    @Column()
    last_msg: string;

    @Column()
    last_msg_created_utc: Date;

    @Column()
    num_messages: number;

    @Column()
    num_replies: number;

    @Column()
    seen: boolean;

}

Problem:

When trying to create a bulk insert on many messages, I can notice that the query is not setting the foreign key any value, but NULL.

The Message json that I'm trying to insert:

{
 id: '1',
 message: 'text',
 receiver: 'someone',
 created_utc: 'utc date...',
 chatRoomId: '123' -> chat room id exists 
}

the query looks like this :
(this query is for single insert not bulk, but it goes the same for bulk)
INSERT INTO "messages"("id", "message", "receiver", "created_utc", "chatRoomId") VALUES ($1, $2, $3, $4, DEFAULT) -- PARAMETERS: [" bJU7","Zdravo test","kompir_zomba","2021-
09-05T09:53:54.693Z"]

This tells me that chatRoomId is not even taken into consideration when inserting the rows. The table looks as following enter image description here

The Typeorm insert query that I use to insert Messages

@InjectRepository(Message) private messageRepository: Repository<Message>
.....

    this.messageRepository.save(message);

Anyone has any idea how to proceed with this ?


Solution

  • I have faced a similar issue with TypeORM when working on a NestJS project.

    Reason:

    The issue is happening because you don't have any chatRoomId field defined in your Message Entity (class Message). So, when TypORM maps your message data with the Message entity, it doesn't set the chatRoomId.

    Solutions:

    There are two solutions to fix this problem.

    1. You can add the chatRoomId field in your Message entity and now you will be able to send the field when saving the message data.

    e.g.

    @Column({type: "uuid"}) // <- Assuming that your primary key type is UUID (OR you can have "char")
    chatRoomId: string;
    

    Now, usually you would not need to create a migration for this since this field already exists in the database table.

    1. The other way is to pass an instance of ChatRoom entity to the message object when saving it.

    You can, first, find the chat room using its ID and then pass it in the message object.

    Your final message object should look like this:

    {
     id: '1',
     message: 'text',
     receiver: 'someone',
     created_utc: 'utc date...',
     chatRoom: chatRoomData // <-- Assuming that chatRoomData contains the ChatRoom entity
    }