TypeORM OneToMany вызывает «ReferenceError: Невозможно получить доступ к« <Entity>»до инициализации» - PullRequest
3 голосов
/ 23 февраля 2020

У меня есть две сущности: Пользователь и Привычка . Пользователь может создать несколько привычек, поэтому я использую отношение OneToMany для пользователя (и ManyToOne для привычки соответственно).

User Entity

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);
    }
}

Habit Entity

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 и создал приложение Nest JS. Версия TypeOrm - "^ 0.2.22" , а версия @ nestjs / typeorm - "^ 6.2.0"

My 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 , и это сработало. Кроме того, в отдельном приложении Nest JS (без Nx) я не могу воспроизвести эту справочную ошибку. Изменение версии ECMAScript target в tsconfig. json также не работало.

Оба объекта используются только в своих службах и не создаются нигде в другом месте.

Я ценю любую помощь. Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Я решил это с помощью autoLoadEntities: true при загрузке конфигурации TypeORM в Nest JS. Обратите внимание, что это Nest JS extra, поэтому, если вы используете ormconfig. json это свойство не будет применено.

Документация autoLoadEntities здесь: https://docs.nestjs.com/techniques/database#auto -load-entity

ОБНОВЛЕНИЕ 04/10/2020

У меня продолжала возникать та же проблема с отношениями. Другое решение, которое я нашел, даже если оно нарушает некоторые стандарты, - добавить все сущности в один файл. Экспортируйте их туда и импортируйте, где это необходимо.

Имейте в виду, что порядок, в котором объявлены классы, имеет значение.

1 голос
/ 15 апреля 2020

В tsconfig установка цели на «esnext» и модуля на «common js» устранила проблему для меня

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "types": ["node", "jest"],
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "target": "esnext"
  },
  "include": ["**/*.ts"]
}
...