I have a Company class with the following definition:
export class Company extends BaseEntity {
@PrimaryGeneratedColumn()
@Field((type) => ID) // needed to overwrite the number typ
id: number;
@Column()
name: string;
@Column()
domain: string;
@OneToMany(() => User, (user) => user.company, {
onDelete: 'SET NULL',
})
users: User[];
@OneToMany(() => Deal, (deal) => deal.company)
deals: Deal[];
}
and when updating a company, the update company dto would contain both a list of dealIds as well as userIds to add to the existing relations. Here is my update method:
async update(id: number, updateCompanyInput: UpdateCompanyInput) {
console.log(`This action updates a #${id} company`);
const queryRunner = this.connection.createQueryRunner();
await queryRunner.connect();
const company = await queryRunner.manager.preload(Company, {
id,
...updateCompanyInput,
});
await queryRunner.manager
.createQueryBuilder()
.relation(Company, 'users')
.of(id)
.add(updateCompanyInput.userIds);
await queryRunner.manager
.createQueryBuilder()
.relation(Company, 'deals')
.of(id)
.add(updateCompanyInput.dealIds);
const result = this.companyRepository.save(company);
await queryRunner.release();
return result;
}
I am wondering:
queryRunner.release()
after this.companyRepository.save
or the order can be more flexible?You do not need to use a transaction. You should use a transaction if and only if you want to undo the added Company, 'users'
relation when something goes wrong adding the Company, 'deals'
relation. Transactions are just a way of making the queries within it atomic (ie all occur or none occur).
As far as query runner releasing - I'm not sure. I haven't used query runner at all. I'm not sure why you are, actually, so maybe this is a bad answer? I use getRepository
for everything. ie either
getRepository(Company).createQueryBuilder('company')
Or
getRepository(Company).find('primary key value')
should both work, assuming you create the connection on server startup.