类型ORM OneToOne 关系级联删除不起作用

TypeORM OneToOne relationship cascade delete not working

提问人:H3lltronik 提问时间:9/10/2021 最后编辑:H3lltronik 更新时间:9/11/2021 访问量:1866

问:

我正在构建一个简单的发票 API。

我有两个类和 ,有两个与 : 和InvoiceAddressInvoiceAddresssenderAddressclientAddress

我希望能够删除和自动删除和 .InvoicesenderAddressclientAddress

我尝试了很多东西,比如添加 ,它们不会被删除。onDelete and CascadeAddress OneToOne

export class Invoice {
    @OneToOne(() => Address, (senderAddress) => senderAddress.invoice, {
        cascade: true,
        onDelete: 'CASCADE',
        eager: true,
    })
    @JoinColumn()
    senderAddress: Address;

    @OneToOne(() => Address, (clientAddress) => clientAddress.invoice, {
        cascade: true,
        onDelete: 'CASCADE',
        eager: true,
    })
    @JoinColumn()
    clientAddress: Address;
}
export class Address {
    @OneToOne(() => Invoice)
    invoice: Invoice;
}

这就是我删除Invoice

async remove(id: number): Promise<Invoice> {
    const invoice = await this.invoiceRepository.findOne(id);
    if (!invoice)
        throw new HttpException('Invoice not found', HttpStatus.NOT_FOUND);

    return await this.invoiceRepository.remove(invoice);
}

这是在生成迁移时生成的:

public async up(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(
            `CREATE TABLE \`invoices-app\`.\`invoice\` (\`id\` int NOT NULL AUTO_INCREMENT, \`createdAt\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`paymentDue\` datetime NOT NULL, \`description\` varchar(255) NOT NULL, \`paymentTerms\` int NOT NULL, \`clientName\` varchar(255) NOT NULL, \`clientEmail\` varchar(255) NOT NULL, \`status\` varchar(255) NOT NULL, \`total\` int NOT NULL, \`senderAddressId\` int NULL, \`clientAddressId\` int NULL, \`userId\` int NULL, UNIQUE INDEX \`REL_39d5b5b8c9b14ee7d3a28ec6be\` (\`senderAddressId\`), UNIQUE INDEX \`REL_2d58047fd2c36422476e1e1fd3\` (\`clientAddressId\`), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
        );

        await queryRunner.query(
            `CREATE TABLE \`invoices-app\`.\`address\` (\`id\` int NOT NULL AUTO_INCREMENT, \`street\` varchar(255) NOT NULL, \`city\` varchar(255) NOT NULL, \`postCode\` varchar(255) NOT NULL, \`country\` varchar(255) NOT NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`,
        );

        await queryRunner.query(
            `ALTER TABLE \`invoices-app\`.\`invoice\` ADD CONSTRAINT \`FK_39d5b5b8c9b14ee7d3a28ec6be3\` FOREIGN KEY (\`senderAddressId\`) REFERENCES \`invoices-app\`.\`address\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`,
        );

        await queryRunner.query(
            `ALTER TABLE \`invoices-app\`.\`invoice\` ADD CONSTRAINT \`FK_2d58047fd2c36422476e1e1fd36\` FOREIGN KEY (\`clientAddressId\`) REFERENCES \`invoices-app\`.\`address\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`,
        );
}

这是我的整个 ER 图

enter image description here

JavaScript nestjs 类型orm

评论


答:

1赞 Kenan Güler 9/10/2021 #1

您需要将反面指定为 和 上的第二个参数,如下所示:senderAddressclientAddress

export class Invoice {
    @OneToOne(() => Address, 
     senderAddress => senderAddress.invoice, // inverse side
     {
        cascade: ['insert'],
        onDelete: 'CASCADE',
        eager: true,
    })
    @JoinColumn()
    senderAddress: Address;

    @OneToOne(() => Address, 
     clientAddress => clientAddress.invoice, // inverse side
     {
        cascade: ['insert'],
        onDelete: 'CASCADE',
        eager: true,
    })
    @JoinColumn()
    clientAddress: Address;
}

评论

0赞 H3lltronik 9/10/2021
谢谢先生,但他们仍然没有被删除
0赞 Kenan Güler 9/10/2021
@H3lltronik,您可能需要再次执行数据库迁移 - 假设您让 TypeORM 使用注释自动生成和修改数据库。
1赞 H3lltronik 9/11/2021
再次感谢你,先生,我更新了我的帖子。我正在使用,然后我将其更改为 false 并使用迁移,但它也不起作用,但我看到了生成代码,并且它正在添加它应该工作的约束,对吧?你能看看吗?synchronize: trueON DELETE CASCADE
1赞 Kenan Güler 9/11/2021
@H3lltronik通常对开发很有帮助,但对生产来说却是个坏主意。在这种情况下,可能不会考虑像我发布的两个小更改,因此您最终会摆弄数据库本身......synchronize: true
0赞 Kenan Güler 9/11/2021
@H3lltronik您创建的迁移看起来没问题。应该可以工作,是的。您可能希望在方法中的事务中运行这些查询,例如upreturn queryRunner.connection.transaction(async (em: EntityManager) => Promise.all([em.query('sql 1...'), em.query('sql 2...')]));