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

NestJS集成Objection.js使用withGraphFetched时报$relation属性读取错误

错误原因

这个报错的核心原因是关联映射中对应的模型类加载结果为undefined,Objection尝试读取其静态属性$relation时触发异常,具体有两个触发点:

  1. 循环依赖导致模型未初始化:ResourceGroupModel和AttributeModel互相导入作为关联模型,TypeScript默认的CommonJS模块加载机制下,循环导入会让其中一个模块在初始化阶段拿到未完成的导出对象,直接赋值给modelClass就会变成undefined。
  2. 模型路径配置错误:AttributeModel中使用了.js后缀的字符串路径加载关联模型,在TypeScript开发环境(如ts-node运行)下,源码目录下只有.ts文件,对应路径找不到.js文件,导致模型加载失败。

修复方案

步骤1:修改关联映射为延迟加载模式

Objection官方支持modelClass传入函数实现延迟加载,等两个模块都初始化完成后才会执行函数返回模型类,从根源解决循环依赖问题,同时弃用易出错的字符串路径配置:

修正resource-group.model.ts

// 原有导入保持不变
export class ResourceGroupModel extends BaseModel {
  static tableName = 'resource_group';

  // 原有字段定义保持不变

  static relationMappings = {
    attributes: {
      modelClass: () => AttributeModel, // 改为函数返回,延迟加载
      relation: Model.ManyToManyRelation,
      join: {
        from: 'resource_group.id',
        through: {
          from: 'resourcegroup_attribute.resource_group_id',
          to: 'resourcegroup_attribute.attribute_id'
        },
        to: 'attribute.id',
      },
    },
  }
}

修正attribute.model.ts

import { BaseModel } from './base.model';
import { Model } from 'objection';
import { ResourceGroupModel } from './resource-group.model'; // 新增导入

export class AttributeModel extends BaseModel {
  static tableName = 'attribute'

  // 原有字段定义保持不变

  static relationMappings = {
    resourceGroups: {
      modelClass: () => ResourceGroupModel, // 替换原有字符串路径
      relation: Model.ManyToManyRelation,
      join: {
        from: 'attribute.id',
        through: {
          from: 'resourcegroup_attribute.attribute_id',
          to: 'resourcegroup_attribute.resource_group_id',
        },
        to: 'resource_group.id',
      },
    },
  }
}

步骤2:修正图查询写法

withGraphFetched官方推荐传入字符串形式的关联名,避免数组写法的兼容问题:

test() {
  return this.model
    .query()
    .withGraphFetched('attributes') // 改为字符串写法
    .where({id: 25});
}

可选检查项

  • 确认你使用的Objection版本 >= 2.0,支持函数形式的modelClass配置。
  • 确认BaseModel已经正确绑定knex实例,启动代码中存在Model.knex(knexInstance)的逻辑。
  • 如果使用@willsoto/nestjs-objection集成包,确认在对应模块中通过ObjectionModule.forFeature([ResourceGroupModel, AttributeModel])注册了两个模型。

内容的提问来源于stack exchange,提问作者TheHiggsBroson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:06:02