Reputation: 1302
I have a basic nestjs app with 3 entities :
document: DocumentEntity
has pages: PageEntity[]
as @OneToMany
relationpage: PageEntity
has words: WordEntity[]
as @OneToMany
relation + @ManyToOne
documentword: WordEntity
has a @ManyToOne
page: PageEntity
This is quite straightforward and the first part of those relations works as expected :
I can save new pages
doing so :
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);
}
}
but when I try to apply the same logic to the words/page
relation, it fails. I m not sure why this behaves differently
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);
}
}
Error Message :
[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
here are the entities declarations :
// 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;
}
Upvotes: 0
Views: 5681
Reputation: 1
You need to remove the primary: true
from your @ManyToOne
relation because a primary relation cannot be set as NULL
Upvotes: 0
Reputation: 1549
Try this:
@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);
}
Upvotes: 4