我有两个实体:用户和习惯。用户可以创建多个习惯,因此我对用户使用OneToMany关系(习惯上分别使用ManyToOne )。
用户实体
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, BeforeInsert, BeforeUpdate, OneToMany} from "typeorm";
import * as bcrypt from "bcryptjs";
import { Habit } from "../habits/habits.entity";
@Entity()
export class User {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
name: string;
@Column()
email: string;
@Column()
password: string;
@OneToMany(type => Habit, habit => habit.author)
habits: Habit[];
@CreateDateColumn()
dateCreated: Date;
@UpdateDateColumn()
dateUpdated: Date;
@BeforeInsert()
@BeforeUpdate()
async hashPassword(): Promise<void> {
this.password = await bcrypt.hash(this.password,10);
}
async comparePassword(password: string): Promise<boolean> {
return bcrypt.compare(password, this.password);
}
constructor(props: any) {
Object.assign(this, props);
}
}
习惯实体
import {Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, ManyToOne} from "typeorm";
import { User } from "../users/users.entity";
@Entity()
export class Habit {
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
name: string;
@Column({ nullable: true})
description?: string;
@ManyToOne(type => User, user => user.habits)
author: User;
@CreateDateColumn()
dateCreated: Date;
@UpdateDateColumn()
dateUpdated: Date;
constructor(props: Partial<Habit>) {
Object.assign(this, props);
}
}
问题
当设置上述关系时,我会收到以下错误
WARNING in Circular dependency detected:
apps\api\src\habits\habits.entity.ts -> apps\api\src\users\users.entity.ts -> apps\api\src\habits\habits.entity.ts
WARNING in Circular dependency detected:
apps\api\src\users\users.entity.ts -> apps\api\src\habits\habits.entity.ts -> apps\api\src\users\users.entity.ts
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "User", function() { return User; });
^
ReferenceError: Cannot access 'User' before initialization
at Module.User (...\dist\apps\api\main.js:1782:96)
at Module../apps/api/src/habits/habits.entity.ts (...\dist\apps\api\webpack:\apps\api\src\habits\habits.entity.ts:42:13)
at __webpack_require__ (...\dist\apps\api\webpack:\webpack\bootstrap:19:1)
at Module../apps/api/src/users/users.entity.ts (...\dist\apps\api\main.js:1790:79)
at __webpack_require__ (...\dist\apps\api\webpack:\webpack\bootstrap:19:1)
at Module../apps/api/src/config/db-config.service.ts (...\dist\apps\api\main.js:1038:77)
at __webpack_require__ (...\dist\apps\api\webpack:\webpack\bootstrap:19:1)
at Module../apps/api/src/config/config.module.ts (...\dist\apps\api\main.js:978:76)
at __webpack_require__ (...\dist\apps\api\webpack:\webpack\bootstrap:19:1)
at Module../apps/api/src/app/app.module.ts (...\dist\apps\api\main.js:147:79)
备注
我使用Nx并创建了一个NestJS应用程序。TypeOrm版本为"^0.2.22",@nestjs/typeorm版本为"^6.2.0"
我的tsconfig如下所示:
{
"compileOnSave": false,
"compilerOptions": {
"rootDir": ".",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"module": "esnext",
"typeRoots": ["node_modules/@types"],
"lib": ["es2018", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {
"@awhile/contracts": ["libs/contracts/src/index.ts"],
"@awhile/ui": ["libs/ui/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]
}
我尝试过使用ManyToMany关系,它起了作用。另外,在一个单独的NestJS应用程序(没有Nx)上,我不能再现这个引用错误。在tsconfig.json中更改ECMAScript 目标版本也不起作用。
这两个实体只在其服务中使用,不在其他任何地方实例化。
我很感谢你的帮助。提前谢谢你。
发布于 2020-04-01 18:28:34
当将autoLoadEntities配置加载到NestJS时,我使用了TypeORM : true来解决这个问题。请注意,这是一个额外的NestJS,因此如果您正在使用ormconfig.json,则不会应用该属性。
这里的autoLoadEntities文档:https://docs.nestjs.com/techniques/database#auto-load-entities
更新04/10/2020
我一直对关系也有同样的看法。我发现的另一个解决方案,即使它破坏了一些标准,也是将所有实体添加到一个文件中。出口到那里,在需要的地方进口。
请记住,类的声明顺序很重要。
发布于 2022-04-23 20:55:27
使用Relation
类型包装器可以避免循环依赖问题,如这里所述。
例如:
import {Entity, OneToMany, Relation} from "typeorm";
import {Habit} from "../habits/habits.entity";
@Entity()
export class User {
...
@OneToMany(type => Habit, habit => habit.author)
habits: Relation<Habit>[];
...
}
发布于 2020-04-15 19:54:07
在tsconfig中,将目标设置为"esnext“,将模块设置为"commonjs”,为我解决了这个问题。
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"types": ["node", "jest"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"target": "esnext"
},
"include": ["**/*.ts"]
}
https://stackoverflow.com/questions/60363353
复制相似问题