You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 16:38:28