I have project entity which has systemInstances. And systemInstance have a manytomany child and parent relation. When I try to update Project entity with same systemInstances, typeorm giving this error
ERROR [ProjectController] Failed to update project version in project.service.ts: QueryFailedError: update or delete on table "system_instance" violates foreign key constraint "FK_3108b2b6c17bb0ed49ad71b131c" on table "system_instance_relationship"
as far as I understand typeorm trying to delete relation data from system_instance_relation table but Im not changing anything inside of the systemInstance, actually Im just passing the same object to save method.
when I save Project into db, systemInstances should be also updated with relations.
Here is my code
async updateDraftVersion(toUpdate: UpdateProjectDto, user: User) {
try {
const id = toUpdate.id;
const project = await this.projectRepository.findOne({
where: {
id: id,
},
relations: [
'createdBy',
'createdBy.userRole',
'systemInstances',
'systemInstances.parent',
'systemInstances.children',
'systemInstances.createdBy',
'systemInstances.createdBy.userRole',
'systemInstances.systemTemplate',
'systemInstances.systemTemplate.systemCategory',
'systemInstances.softwarePackages',
],
});
if (!project) {
throw new APIError(
HttpStatus.NOT_FOUND,
`Can not found project with Id: ${id}`,
);
}
project.name = toUpdate.name;
project.description = toUpdate.description;
project.yardNumber = toUpdate.yardNumber;
const updatedItem = await this.projectRepository.save(project);
return updatedItem;
} catch (e) {
if (e instanceof APIError) {
throw e;
} else {
throw new APIError(
HttpStatus.INTERNAL_SERVER_ERROR,
`Failed to update project version in project.service.ts: ${e}`,
);
}
}
}
here is my Project Entity
@Entity()
export class Project extends BaseEntity {
@Column({ type: 'text', nullable: false })
yardNumber: string;
@Column({ type: 'text', nullable: false })
name: string;
@Column({ type: 'text', nullable: false })
description: string;
@Column({ type: 'text', default: VersionStatus.DRAFT, nullable: false })
status: string;
@Column({ type: 'numeric', default: 1, nullable: false })
version: number;
@OneToMany(() => SystemInstance, (system) => system.project, { cascade: true, onDelete:'CASCADE', onUpdate:'CASCADE' })
systemInstances: SystemInstance[];
}
and system.instance.entity
@Entity()
export class SystemInstance extends BaseEntity {
@Column({ type: 'text', nullable: false })
systemId: string;
@Column({ type: 'text', nullable: false })
name: string;
@Column({ type: 'text', nullable: false })
description: string;
@ManyToOne(() => SystemTemplate, (systemTemplate) => systemTemplate.systems)
systemTemplate: SystemTemplate;
@ManyToOne(() => Project, (project) => project.systemInstances,
{ orphanedRowAction: 'delete' }
)
project: Project;
@ManyToMany(() => SystemInstance, (system) => system.children)
@JoinTable({
name: 'system_instance_relationship',
joinColumn: { name: 'child_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'parent_id', referencedColumnName: 'id' },
})
parent: SystemInstance;
@ManyToMany(() => SystemInstance, (system) => system.parent, { cascade: true, orphanedRowAction: 'delete' })
@JoinTable({
name: 'system_instance_relationship',
joinColumn: { name: 'parent_id', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'child_id', referencedColumnName: 'id' },
})
children: SystemInstance[];
@ManyToMany(
() => SoftwarePackage,
(softwarePackage) => softwarePackage.systemTemplates,
)
@JoinTable({
name: 'system_instance_software_package',
joinColumn: { name: 'system_instance_id', referencedColumnName: 'id' },
inverseJoinColumn: {
name: 'software_package_id',
referencedColumnName: 'id',
},
})
softwarePackages: SoftwarePackage[];
}