I have a candidate entity with many "ManyToMany" relations, I need to create an update function for this entity. Here is my candidate entity:
@Entity()
export class Candidate {
@PrimaryGeneratedColumn()
id: number;
...
@ManyToMany(() => Language, { nullable: true })
@JoinTable()
languages: Language[];
@ManyToMany(() => Tool, { nullable: true })
@JoinTable()
tools: Tool[];
@ManyToMany(() => ActivityArea, { nullable: true })
@JoinTable()
activity_areas: ActivityArea[];
...
@Column({ nullable: true })
desired_starting_date: string;
...
}
Language entity (the others are similar):
@Entity()
export class Language {
@PrimaryGeneratedColumn()
id: number;
@Column({unique: true})
name: string;
}
I tried to use the update function of typeORM :
async update(id: number, updateCandidateDto: UpdateCandidateDto) {
try {
const candidate = this.generateaCandidate(updateCandidateDto); // this is the new value of candidate
return await this.candidateRepository.update({
id
}, {
languages: candidate.languages,
tools: candidate.tools,
activity_areas: candidate.activity_areas,
desired_starting_date: candidate.desired_starting_date
});
} catch (error) {
throw new HttpException(error.detail, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
But I got the following error : Error: Cannot query across many-to-many for property tools
I check the following post before posting this one: Update a many-to-many relationship with TypeORM Typeorm (Nestjs) update ManyToMany relation when using querybuilder violates not-null constraint TypeORM updating entity/table
Can you help me to build an update function that allows me to update several ManyToMany parameters?
I finaly found a way to did it :
async update(id: number, updateCandidateDto: UpdateCandidateDto) {
try {
const new_candidate = await this.generateCandidate(updateCandidateDto);
for (const prop in new_candidate) {
if (typeof new_candidate[prop] == 'object') {
const actualRelationships = await this.candidateRepository
.createQueryBuilder()
.relation(Candidate, prop)
.of(id)
.loadMany();
await this.candidateRepository
.createQueryBuilder()
.relation(Candidate, prop)
.of(id)
.addAndRemove(new_candidate[prop], actualRelationships);
} else {
const json = JSON.parse(`{ "${prop}" : "${new_candidate[prop]}" }`);
this.candidateRepository
.createQueryBuilder()
.update(Candidate)
.set(json)
.where('id = :id', {id: id})
.execute();
}
}
return await this.findOne(id);
} catch (error) {
console.error(error);
throw new HttpException('Update failed', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
I test each property of the candidate I want to modify, if the property is of type 'object' it means that it is a foreign key. In this case, I retrieve all its relations from the database and replace them with the new relations.
This solution works, I will use it until a better solution is proposed.