NestJS集成Sequelize调用findAll()时报错TypeError: Cannot convert undefined or null to object
看起来你遇到的问题挺棘手的——创建数据正常,但查询就报错,而且编译完全没问题。结合你的代码和技术栈,我帮你梳理几个最可能的原因和解决方案,你可以逐一排查试试:
1. JSONB字段默认值的写法问题
你的events_history字段用了@Default([])搭配DataType.JSONB,这很可能是问题的根源。在Sequelize处理JSON类型字段时,直接用数组字面量[]作为默认值,会导致序列化/反序列化时出现引用或类型解析问题,尤其是在旧版本的Sequelize中。
修改方案:把默认值改成函数形式,确保每次生成新的数组实例:
@AllowNull(false) @Default(() => []) // 改成函数返回空数组 @Column(DataType.JSONB) events_history: IEventHistory[];
2. 模型泛型定义不完整
你的CubeBookingModel继承Model时只传了ICreateCubeBooking,但Sequelize的Model泛型需要两个参数:实例类型和创建DTO类型。如果泛型定义不全,可能导致运行时Sequelize无法正确解析模型的字段元数据,进而在查询时出错。
修改方案:补全泛型参数:
// 第一个参数是模型实例本身的类型,第二个是创建DTO类型 export class CubeBookingModel extends Model<CubeBookingModel, ICreateCubeBooking> { // ... 你的所有字段定义 }
3. 版本兼容性问题
你使用的Sequelize 6.17.0和sequelize-typescript可能存在版本不匹配的情况。旧版本的sequelize-typescript在处理模型元数据时可能有bug,导致查询方法无法正常工作。
检查方案:
- 确认你的
sequelize-typescript版本是2.1.x及以上(对应Sequelize 6.x) - 尝试升级到兼容的最新版本:
npm install sequelize-typescript@latest
4. 模型重复加载的冲突
你在SequelizeModule.forRoot中设置了autoLoadModels: true,同时又在CubeModule里用SequelizeModule.forFeature([CubeBookingModel])手动注册模型,这可能导致模型被重复加载,元数据混乱。
测试方案:暂时把autoLoadModels改成false,重启服务后再调用查询接口:
SequelizeModule.forRoot({ // ... 其他配置 autoLoadModels: false, // 临时关闭自动加载 synchronize: false, }),
如果问题解决了,说明是重复加载导致的,你可以选择保持手动注册模型,或者调整自动加载的配置避免冲突。
额外调试技巧
你可以在getAllBookings方法里加一行打印,查看模型的字段元数据是否正常:
async getAllBookings( status?: BookingStatusType, payment_status?: PaymentStatusType, ): Promise<CubeBookingModel[]> { try { console.log('模型字段元数据:', this.bookingModel.rawAttributes); // 打印字段定义 const bookings = await this.bookingModel.findAll(); console.log(bookings); return bookings; } catch (error) { console.error('错误栈:', error.stack); // 打印完整错误栈,定位具体出错位置 console.error('Errorrrrrrrrrrrrrrrrrr....'); console.error(error); throw new InternalServerErrorException( null, 'Error while fetching bookings', ); } }
如果某个字段的元数据是undefined,那就能直接定位到问题字段了。
备注:内容来源于stack exchange,提问作者Lex Nwimue P.

