NestJS+TypeORM关联PostgreSQL视图报错,求解决方案
解决TypeORM视图实体关联报错:Relation UsersView.profiles does not have join columns
问题场景
在NestJS中使用TypeORM关联PostgreSQL的两个视图实体view_users和view_profiles时,执行关联查询出现以下错误:
Relation UsersView.profiles does not have join columns.
期望实现类似普通表的关联查询,得到包含用户关联资料的嵌套结构。
错误原因
在UsersView实体的@OneToMany关联上错误添加了@JoinColumn装饰器。TypeORM的关联规则中:
@OneToMany关联的主实体(UsersView)不需要@JoinColumn,关联关系由反向的@ManyToOne实体(ProfilesView)通过外键维护@JoinColumn仅需在@ManyToOne的一方使用,用来指定外键列(这里是ProfilesView的userId)
修正后的代码
UsersView 实体(修正后)
移除@OneToMany上的@JoinColumn装饰器:
import { OneToMany, ViewColumn, ViewEntity } from 'typeorm'; import { ProfilesView } from 'src/modules/profiles/entity/profiles.entity'; @ViewEntity({ name: 'view_users', expression: `SELECT * FROM users`, }) export class UsersView { @ViewColumn() id: number; @ViewColumn() userName: string; @ViewColumn() email: string; @ViewColumn() phoneNumber: string; @ViewColumn() createdAt: Date; @ViewColumn() updatedAt: Date; @ViewColumn() phoneCountryCode: string; @ViewColumn() deletedAt: Date; @ViewColumn() isBlacklist: boolean; @ViewColumn() fcmNotificationId: string; // 仅保留@OneToMany和反向关联字段,移除@JoinColumn @OneToMany(() => ProfilesView, (profiles) => profiles.user) profiles: ProfilesView[]; }
ProfilesView 实体(无需修改)
现有代码的@ManyToOne关联配置正确,保持不变:
import { JoinColumn, ManyToOne, ViewColumn, ViewEntity } from 'typeorm'; import { UsersView } from 'src/modules/users/entity/users.entity'; @ViewEntity({ name: 'view_profiles', expression: `SELECT * FROM profile`, }) export class ProfilesView { @ViewColumn() id: number; @ViewColumn() name: string; @ViewColumn() gender: string; @ViewColumn() phoneNumber: string; @ViewColumn() phoneCountryCode: string; @ViewColumn() email: string; @ViewColumn() identityCardNumber: string; @ViewColumn() isPatient: number; @ViewColumn() birthDate: Date; @ViewColumn() userId: number; @ViewColumn() unlocked: number; @ViewColumn() linked: number; @ViewColumn() createdAt: Date; @ViewColumn() updatedAt: Date; @ViewColumn() bpjsCardNumber: string; @ViewColumn() hasBpjs: number; @ViewColumn() deletedAt: Date; @ManyToOne(() => UsersView, (user) => user.profiles) @JoinColumn({ name: 'userId' }) user: UsersView; }
适配期望结果的字段名(可选)
如果需要返回结果中的字段名为profile(而非profiles),需同步修改两个实体的关联字段名:
- UsersView中修改关联字段:
@OneToMany(() => ProfilesView, (profiles) => profiles.user) profile: ProfilesView[]; - ProfilesView中修改反向关联指向:
@ManyToOne(() => UsersView, (user) => user.profile) @JoinColumn({ name: 'userId' }) user: UsersView;
验证结果
修改完成后,调用UsersService的getData方法,即可得到符合期望的嵌套关联结果:
[ { "id": 1, "phoneNumber": "xxxx", "profile": [ { "id": 1, "name": "xxx" }, { "id": 2, "name": "xxx" } ] } ]
内容的提问来源于stack exchange,提问作者Robby Izhar Ramadhana
相关产品推荐
相关产品推荐

