TypeORM更新实体报错Cannot query across one-to-many for property members如何解决
问题原因
你触发报错的核心原因是调用_personRepository.update(id, person)时,传入的person实体对象包含members这个@OneToMany类型的关联属性,TypeORM的update方法仅支持更新实体普通字段、以及关联的拥有方(比如你代码中的fare属于@ManyToOne,是Person作为拥有方的关联,支持更新),无法直接处理反向一对多关联属性,因此抛出该错误。
另外你的代码还有一个隐藏问题:Repository.update()方法返回的是UpdateResult类型对象(仅包含影响行数等更新统计信息),不是更新后的Person实体,你当前控制器直接返回updatedPerson不符合预期。
解决方案
以下任选一种即可:
方案1(最推荐):仅传入需要更新的字段
不要把整个Person实体传入update方法,单独构造只包含待更新字段的纯对象,避免带上members关联属性:
// 控制器逻辑修改 router.put('/persons/:id', async (req: Request, res: Response) => { const id = +req.params.id; const person = await this._personService.readOne(id); if (!person) { return res.status(400).send('Person not found') } const { lastName, firstName, address, email, phone, fareId } = req.body; const updateFields: Partial<Person> = {}; if (fareId) { const fare = await this._fareService.readOne(fareId); if (!fare) { return res.status(400).send('Fare not found') } updateFields.fare = fare; } if (lastName) updateFields.lastName = lastName; if (firstName) updateFields.firstName = firstName; if (address) updateFields.address = address; if (email) updateFields.email = email; if (phone) updateFields.phone = phone; await this._personService.update(updateFields, id); // 返回更新后的实体,需要重新查询一次 const updatedPerson = await this._personService.readOne(id); res.send(updatedPerson); });
方案2:移除实体中的OneToMany属性再传入update
如果你想保留原有实体赋值的写法,只需要在调用update前删除members属性即可:
// 控制器中赋值完成后,加一行删除逻辑 delete person.members; const updatedPerson = await this._personService.update(person,id);
方案3:改用save方法代替update
Repository.save()方法会基于实体主键匹配更新,支持处理实体关联,修改服务层代码即可:
// 服务层update方法修改 public update = async (person: Person) => { return await this._personRepository.save(person); } // 控制器调用时不需要传id,直接传修改后的person实体 const updatedPerson = await this._personService.update(person); res.send(updatedPerson);
内容的提问来源于stack exchange,提问作者Eurydice
相关产品推荐
相关产品推荐

