Reputation: 16359
I am having issues updating a entity that has a many-to-many reln, curious if I am doing something wrong, or more specifically what is the right way to do this
Consider the following entities ...
@Entity
class Subject
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@ManyToMany(() => Note, note => note.subjects)
@JoinTable()
notes: Note[];
...
@Entity()
export class Note {
@PrimaryGeneratedColumn('uuid')
id: string;
@ManyToMany(() => Subject, (subject: Subject) => subject.notes)
subjects: Subject[];
In my code I find the node and then try to update it and save like so ...
const note = await noteRepo.findOneOrFail(noteId);
const foundSubjects = await subjectRepo.findByIds(Array.from(subjectIds));
note.subjects = foundSubjects;
noteRepo.save(note);
But alas, the subjects are not saved on the note.
What is the right way to do this?
Thanks!
Upvotes: 18
Views: 38764
Reputation: 944
Use the save method instead of update.
repo.save({id:1, subjects:[{id:1},{id:2}]})
Upvotes: 0
Reputation: 410
Check this answer: How to update an entity with relations using QueryBuilder in TypeORM
It worked for me.
...
note.subjects = foundSubjects;
const toUpdate = await noteRepo.preload(note)
noteRepo.save(toUpdate);
Don't forget the await
, is missing in the answer, or is somthing to do with eager: true
... I'm not sure.
Upvotes: 1
Reputation: 887
In my case Im trying to update an existing relation but that gives me a unique key violation because the relation already exists, so I first need to remove all existing relationships and then add the relationships of my updated user:
export const updateUser = async (user: User): Promise<User | undefined> => {
/**
* Get the actual relationships of that user.
*/
const actualRelationships = await getRepository(User)
.createQueryBuilder()
.relation(User, 'roles')
.of(user).loadMany();
/**
* Add new relationships of the user, and delete the old relationships.
*/
await getRepository(User)
.createQueryBuilder()
.relation(User, 'roles')
.of(user)
.addAndRemove(user.roles, actualRelationships);
/**
* Update only the table USER.
*/
await getRepository(User)
.createQueryBuilder()
.update()
.set({
name: user.name,
username: user.username,
active: user.active
})
.where('id = :id', {id: user.id})
.execute();
/**
* Return the updated user
*/
return await getUser(user.id, true, true)
};
Upvotes: 17
Reputation: 1849
By default cascading is set to false, you can enable this as follows:
@Entity()
export class Note {
@PrimaryGeneratedColumn('uuid')
id: string;
@ManyToMany(() => Subject, (subject: Subject) => subject.notes, { cascade: true })
subjects: Subject[];
Upvotes: 5
Reputation: 16359
So the following got it working for me:
subjectIds.forEach(async id => {
await connection
.createQueryBuilder()
.relation(Note, 'subjects')
.of(note)
.add(id);
});
Though, I still kind of feel that the repo.save() method should work
Upvotes: 8