TypeORM 插入带有外键的行

Lik*_*iki 6 postgresql node.js typescript typeorm

我在
Chatroom < 1 ---- M > Messages之间有一个 @OneToMany 关系
,我遇到的问题是,每当我尝试插入一条消息(或大量消息)时,ChatRoom 的外键为空。
此外,我正在上传我的设置。

@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;
}
Run Code Online (Sandbox Code Playgroud)
@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;

}
Run Code Online (Sandbox Code Playgroud)

问题:

当尝试对许多消息创建批量插入时,我注意到查询没有将外键设置为任何值,而是设置NULL

我尝试插入的消息 json:

{
 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"]
Run Code Online (Sandbox Code Playgroud)

这告诉我在插入行时甚至没有考虑 chatRoomId。该表如下所示 在此输入图像描述

我用来插入消息的 Typeorm 插入查询

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

    this.messageRepository.save(message);
Run Code Online (Sandbox Code Playgroud)

有人知道如何继续吗?

小智 7

在处理 NestJS 项目时,我也遇到过类似的 TypeORM 问题。

原因:

发生此问题的原因是您的消息实体( )chatRoomId中没有定义任何字段。因此,当 TypORM 将消息数据与Message 实体映射时,它不会设置.class MessagechatRoomId

解决方案:

有两种解决方案可以解决此问题。

  1. chatRoomId您可以在实体中添加该字段Message,现在您将能够在保存消息数据时发送该字段。

例如

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

现在,通常您不需要为此创建迁移,因为该字段已存在于数据库表中。

  1. 另一种方法是在保存对象时将ChatRoom实体的实例传递给message对象。

您可以首先使用 ID 找到聊天室,然后将其传递到消息对象中。

你的最终message对象应该是这样的:

{
 id: '1',
 message: 'text',
 receiver: 'someone',
 created_utc: 'utc date...',
 chatRoom: chatRoomData // <-- Assuming that chatRoomData contains the ChatRoom entity
}
Run Code Online (Sandbox Code Playgroud)

  • 当然,忘记了。对于未来的读者来说,对于解决方案2,你不需要传递所有的数据(如果你没有级联更新..),你可以只传递带有ID字段的Entity(其他为空),它仍然会工作。 (3认同)
  • 谢谢 !!经过昨晚的实验后,我得到了你的解决方案,但我不太喜欢它。解决方案 1 更加简洁,我喜欢它。多谢! (2认同)