Sequelize查询Credentials时报错:Cannot convert undefined or null to object
Sequelize查询Credentials模型报错及关联问题解决
错误信息
TypeError: Cannot convert undefined or null to object at hasOwnProperty (<anonymous>) at credentials._paranoidClause (C:\bots\Trion\node_modules\sequelize\lib\model.js:176:65) at credentials.findAll (C:\bots\Trion\node_modules\sequelize\lib\model.js:1135:20) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async credentials.findOne (C:\bots\Trion\node_modules\sequelize\lib\model.js:1240:12) at async login (file:///C:/bots/Trion/routes/auth.js:77:21)
模型定义
User.js
import { DataTypes } from "sequelize"; import { sequelize } from './SQL.js'; const User = sequelize.define("user", { id: { type: DataTypes.INTEGER, autoIncrement: true, primaryKey: true, allowNull: false }, anonymous: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: true }, username: { type: DataTypes.STRING, allowNull: false, unique: true }, avatarBlob: { type: DataTypes.BLOB } }, { sequelize, tableName: "user", timestamps: true, createdAt: "createdAt", updatedAt: false, deletedAt: "deletedAt", paranoid: true }); User.hasOne(Credentials, { sourceKey: 'id', foreignKey: 'userId', onUpdate: 'CASCADE', onDelete: 'CASCADE' }); Credentials.belongsTo(User); export { User };
Credentials.js
import { DataTypes } from "sequelize"; import { sequelize } from './SQL.js'; import { User } from './User.js'; const Credentials = sequelize.define("credentials", { userId: { type: DataTypes.INTEGER, unique: true, allowNull: false }, password: { type: DataTypes.STRING, allowNull: false, }, salt: { type: DataTypes.STRING, allowNull: false, } }, { sequelize, tableName: "credentials", timestamps: true, createdAt: false, updatedAt: "updatedAt", deletedAt: false, paranoid: true }); export { Credentials };
问题场景
执行以下代码时触发错误:
let user = await User.findOne({ where: { username: payload.username } }); let creds = await Credentials.findOne({ where: { userId: user.id } });
尝试过的操作:
- 原生SQL查询可正常返回结果:
'SELECT * FROM credentials WHERE credentials."userId" = ' + user.id + ';'
- 使用Sequelize关联查询仍报错:
await User.findOne({ where: { username: payload.username }, include: Credentials });
- 尝试调用
User.getCredentials()方法,发现方法不存在
问题根源及修复方案
1. 循环依赖导致关联未正确初始化
User模型中直接引用了未加载完成的Credentials,Credentials又反向导入User,导致关联关系在模型初始化阶段未正确建立,进而引发后续方法调用异常。
修复:
将关联定义抽离到单独文件(如associations.js),确保所有模型加载完成后再初始化关联:
// associations.js import { User } from './User.js'; import { Credentials } from './Credentials.js'; User.hasOne(Credentials, { sourceKey: 'id', foreignKey: 'userId', onUpdate: 'CASCADE', onDelete: 'CASCADE' }); Credentials.belongsTo(User);
在项目入口文件(如app.js)中优先导入该文件:
import './associations.js'; // 后续导入其他业务代码
2. Paranoid模式配置冲突
Credentials模型开启了paranoid: true(软删除),但设置了deletedAt: false,Sequelize启用软删除必须指定有效的deletedAt字段,否则内部处理时会出现空值引用错误。
修复二选一:
- 保留软删除:添加
deletedAt字段配置
// Credentials.js 模型配置部分 { sequelize, tableName: "credentials", timestamps: true, createdAt: false, updatedAt: "updatedAt", deletedAt: "deletedAt", // 启用软删除字段 paranoid: true }
- 关闭软删除:将
paranoid设为false
// Credentials.js 模型配置部分 { sequelize, tableName: "credentials", timestamps: true, createdAt: false, updatedAt: "updatedAt", deletedAt: false, paranoid: false // 关闭软删除 }
3. 验证修复效果
修复后,关联查询和自动生成的方法均可正常使用:
// 关联查询示例 const user = await User.findOne({ where: { username: payload.username }, include: [{ model: Credentials }] }); const creds = user.credentials; // 调用自动生成的方法 const user = await User.findOne({ where: { username: payload.username } }); const creds = await user.getCredentials();
内容的提问来源于stack exchange,提问作者Merilax
相关产品推荐
相关产品推荐

