TypeORM PostgreSQL @ManyToOne 保存违反非空约束
TypeORM PostgreSQL @ManyToOne save violates not-null constraint
我有一个包含 3 个实体的基本 nestjs 应用程序:
document: DocumentEntity
有 pages: PageEntity[]
作为 @OneToMany
关系
page: PageEntity
有 words: WordEntity[]
as @OneToMany
关系 + @ManyToOne
文档
word: WordEntity
有一个 @ManyToOne
page: PageEntity
这很简单,这些关系的第一部分按预期工作:
这样做我可以保存新的 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
我有一个包含 3 个实体的基本 nestjs 应用程序:
document: DocumentEntity
有pages: PageEntity[]
作为@OneToMany
关系page: PageEntity
有words: WordEntity[]
as@OneToMany
关系 +@ManyToOne
文档word: WordEntity
有一个@ManyToOne
page: PageEntity
这很简单,这些关系的第一部分按预期工作:
这样做我可以保存新的 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