【问题标题】:TypeORM cascade: true flag does not delete related entitiesTypeORM级联:true标志不删除相关实体
【发布时间】:2020-12-24 00:30:32
【问题描述】:

我不知道是不是我,cascade: true 选项在删除父实体时不会删除子实体?

@Entity()
export class Folder {
  @PrimaryGeneratedColumn()
  public readonly id: number;

  @OneToMany(() => Segment, (segment) => segment.folder, {
    cascade: true,
  })
  public segments: Segment[];
}


@Entity()
export class Segment {
  @PrimaryGeneratedColumn()
  public readonly id: number;

  @ManyToOne(() => Folder, (folder) => folder.segments)
  @JoinColumn()
  public folder: Folder;
}

然后我做

await getRepository(Folder).delete(id);

这给了我一个错误:

update or delete on table "folder" violates foreign key constraint "FK_12606f83d18e5ae0c7e5693f3fb" on table
"segment"

也试过了

const folder = await this.repository.findOneOrFail(id);
repository.remove(folder)
//or 
folder.segments = null;
await this.repository.save(folder);

还是错误...

我不想遍历所有子实体并手动删除它们。我认为cascade: true 应该处理它以及保存或更新。 也许语法应该不同?

谢谢!

【问题讨论】:

    标签: typescript typeorm


    【解决方案1】:

    级联只描述了如何处理相关实体,当实体本身被删​​除时它没有效果。如果要在删除文件夹时删除所有段,则需要使用 onDelete (这是数据库功能,否则使用 cascade,它在 TypeORM 中实现。这意味着您需要在何时生成并执行迁移添加 onDelete)。所以这应该适合你:

    @Entity()
    export class Segment {
      @PrimaryGeneratedColumn()
      public readonly id: number;
    
      @ManyToOne(() => Folder, (folder) => folder.segments, { onDelete: 'CASCADE' })
      @JoinColumn()
      public folder: Folder;
    }
    

    【讨论】:

    • 完全正确,关于 onDelete: 'Cascade'。我也使用这个功能。我无法弄清楚 - 他们出于什么原因将“删除”添加到级联选项?应该有一个原因和使用它的方式。
    • 我一直认为删除选项允许您删除关系。所以你有一个包含两个段的文件夹,然后设置 folder.segments = [] 然后保存它(等待 this.repository.save(folder)),然后 TypeORM 删除关系,但保留段。这目前正在工作,但是当将级联更改为“级联:['插入']”时,删除行为仍然有效,这是我没想到的。所以是的,我不能确切地告诉你“级联:['remove']”的作用。
    • 是的,有趣,顺便说一句。为什么我做了 folder.segments = [] 它试图删除关系,但将段项保留在数据库中。但在这种情况下,出现了一个数据库错误,例如“folder_id 不能为空”。所以可能需要隐式设置该段实体可以有孤儿......无论如何,谢谢你的回应。
    【解决方案2】:

    这是 typeorm 代码中的一个“错误”(不确定它是否是所需的行为),我使用 https://www.npmjs.com/package/patch-package 修复了这个问题,因为我需要尽快修复此问题

    您需要使用此代码修补node_modules/typeorm/persistence/subject-builder/OneToManySubjectBuilder.js 处的文件(- 是您需要删除的内容,+ 是您需要添加的内容):

                 var removedRelatedEntitySubject = new Subject_1.Subject({
                     metadata: relation.inverseEntityMetadata,
                     parentSubject: subject,
    -                canBeUpdated: true,
    +                canBeUpdated: !relation.isNullable,
    +                mustBeRemoved: relation.isNullable,
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多