在使用 NestJS 中的 TypeORM 时,我们经常会使用save方法来保存实体数据到数据库中。然而,在使用save方法时,特别是在修改已有数据并涉及到关联关系时,可能会遇到一些潜在的问题,导致数据丢失、数据不完整的情况。
问题描述
假设我们有两个实体:User和Post,它们之间存在一对多的关系,一个用户可以拥有多篇文章。现在,我们想要修改某个用户姓名,并使用save方法来保存这个修改。
typescriptCopy code
@Entity()
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@OneToMany(() => Post, post => post.user)
posts: Post[];
}
@Entity()
export class Post extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => User, user => user.posts)
user: User;
}
const id=1;
const user = await this.userRepo.findOne({where: { post: {id}}, relations: ['post']});
user.username = 'jack';
await this.userRepo.save(user);
问题出现在,如果我们通过 Post 的 id 做关联查出用户实体,然后修改完 User username, 然后 SAVA, 就会出现数据丢掉的情况了。
原因出现在,这个查出的 user 下的 post 只有 ID=1 的一个数, 不是全部数组。保存时, 可能是因为 TypeORM 在默认情况下进行了级联操作,可能导致一些关联信息在保存时被修改。SAVA 方法保存关联关系。这样, POST 只有 ID=1的实体了。
解决方案
其实要解决这个问题不难
- 查 USER 时, 不要带关联关系。这样保存时就会保存到级联关系。 可以直接用 USER 的 ID 去查,或者用 POST 的 ID 查出 USER 时, 不要用 relations,用 join 只有关联,不查出数据。
await this.userRepo.createQueryBuilder('user')
.leftJoin('user.post', 'post')
.where('post.id = :id', { id })
.getOne()
- 更新数据用 update, 这样只会更新少量数据,不会更新到关联关系。