NestJS更新PostgreSQL后返回空对象问题求助
解决PostgreSQL + TypeORM更新后返回空对象的问题
嘿,我之前也碰到过类似的坑!你说调用updateUserById返回空对象{},但getUsers能正常返回数组,咱们从几个常见的方向排查:
1. 先检查实体类的属性映射
首先确认你的User实体类里,所有要返回的属性都正确加了@Column()装饰器,没有遗漏或者设置了select: false(这个会导致查询时不返回该字段)。举个正确的实体例子:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column() surname: string; @Column() email: string; @Column({ nullable: true }) // 如果允许为空的话 profile_image: string; }
要是某个属性没加@Column(),TypeORM不会把它和数据库列关联,自然返回的时候就不会有这个字段,甚至整个对象序列化后变成空的。
2. 尝试刷新实体实例再返回
有时候TypeORM的save方法不会自动刷新内存中的实体实例(尤其是当你先getOne获取实例再修改保存时)。你可以在save之后调用refresh方法,确保实例是最新的:
public async updateUserById(patchUser: CreateUserDto, userId: number, profile_image: any) { const user = await this._userRepository.createQueryBuilder('user') .where('user.id = :id', {id: userId}) .getOne(); if(!user) { throw new InternalServerErrorException(`User with id ${userId} does not exist`); } user.name = patchUser.name; user.surname = patchUser.surname; user.profile_image = profile_image.location; user.email = patchUser.email; await this._userRepository.save(user); // 关键:刷新实体,确保内存中的实例和数据库同步 await this._userRepository.manager.refresh(user); return user; }
3. 改用update + findOne的方式(更高效也更稳妥)
其实这种先查询再修改保存的方式,不如直接用update更新,然后重新查询返回更靠谱,还能减少一次数据库交互:
public async updateUserById(patchUser: CreateUserDto, userId: number, profile_image: any) { const updateResult = await this._userRepository.update(userId, { name: patchUser.name, surname: patchUser.surname, profile_image: profile_image.location, email: patchUser.email, }); if (updateResult.affected === 0) { throw new InternalServerErrorException(`User with id ${userId} does not exist`); } // 更新完成后重新查询用户返回 return this._userRepository.findOneBy({ id: userId }); }
这种方式返回的是从数据库最新查询出来的对象,不会有内存实例不同步的问题。
4. 检查序列化配置(NestJS专属)
如果你用的是NestJS,还要看看是不是全局或者控制器用了ClassSerializerInterceptor,同时实体里有没有用@Exclude()装饰器不小心把所有属性都排除了?要是有的话,需要给要返回的属性加@Expose():
import { Exclude, Expose } from 'class-transformer'; @Entity() @Exclude() // 全局排除,需要暴露的属性单独加@Expose export class User { @Expose() @PrimaryGeneratedColumn() id: number; @Expose() @Column() name: string; // 其他需要返回的属性同理加@Expose }
试试上面的方法,应该能解决你的问题!
内容的提问来源于stack exchange,提问作者Kruger
相关产品推荐
相关产品推荐

