TypeORM PostgreSQL @ManyToOne 保存违反非空约束

TypeORM PostgreSQL @ManyToOne save violates not-null constraint

我有一个包含 3 个实体的基本 nestjs 应用程序:

这很简单,这些关系的第一部分按预期工作: 这样做我可以保存新的 pages :

  async createPage(documentId: number, url: string) {
    const document = await this.documentRepository.findOne({ id: documentId });
    if (document) {
      const pageEntity = new PageEntity();
      pageEntity.imgUrl = url;
      pageEntity.document = document;
      await this.pageRepository.save(pageEntity);
    }
  }

但是当我尝试将相同的逻辑应用于 words/page 关系时,它失败了。我不确定为什么这会有所不同

async postWord(pageId: number, word: { text: string }) {
    const page = await this.pageRepository.findOne({ id: pageId });
    if (page) {
      const wordEntity = new WordEntity();
      wordEntity.text = word.text;
      wordEntity.page = page;
      await this.wordRepository.save(wordEntity);
    }
  }

错误信息:

[ExceptionsHandler] null value in column "pageId" of relation "word_entity" violates not-null constraint +107723ms
QueryFailedError: null value in column "pageId" of relation "word_entity" violates not-null constraint

这是实体声明:

// document.entity.ts

@Entity()
class DocumentEntity {
  @PrimaryGeneratedColumn()
  public id?: number;

  @Column()
  public name: string;

  @Column()
  public locale: string;

  @Column()
  public pdfUrl: string;

  @Column()
  public folderPath: string;

  @OneToMany(() => PageEntity, (page) => page.document, {
    primary: true,
    eager: true,
    cascade: true,
  })
  public pages?: PageEntity[];
}

export default DocumentEntity;

// page.entity.ts

@Entity()
class PageEntity {
  @PrimaryGeneratedColumn()
  public id?: number;

  @Column({ nullable: true })
  public pageNumber?: number;

  @Column({ nullable: true })
  public text?: string;

  @Column()
  public imgUrl: string;

  @OneToMany(() => WordEntity, (word) => word.page, {
    eager: true,
    onDelete: 'CASCADE',
    primary: true,
  })
  words?: WordEntity[];

  @ManyToOne(() => DocumentEntity, {
    primary: true,
    onDelete: 'CASCADE',
  })
  @JoinColumn()
  public document: DocumentEntity;
}

export default PageEntity;

// word.entity.ts
@Entity()
class WordEntity {
  @PrimaryGeneratedColumn()
  public id?: number;

  @ManyToOne(() => PageEntity, {
    nullable: true,
    primary: true,
    onDelete: 'CASCADE',
  })
  @JoinColumn()
  public page!: PageEntity;

  @Column()
  public text: string;

  @Column({ type: 'decimal', nullable: true })
  public confidence?: number;
}


试试这个:

@Entity()
class WordEntity {
  .....

  @ManyToOne(() => PageEntity, {
    nullable: true,
    primary: true,
    onDelete: 'CASCADE',
  })
  @JoinColumn({
    name: 'pageId',
    referencedColumnName: 'id',
  })
  page?: PageEntity;

  @Column({ nullable: true })
  pageId?: number

  .....

}

async postWord(pageId: number, word: { text: string }) {
      const wordEntity = new WordEntity();
      wordEntity.text = word.text;
      // check if the pageId exists, maybe inside Dto with a decorator
      wordEntity.pageId = pageId;
      await this.wordRepository.save(wordEntity);
  
  }

您需要从 @ManyToOne 关系中删除 primary: true,因为不能将主要关系设置为 NULL