简体   繁体   English

RepositoryNotFoundError:找不到“用户”的存储库。 看起来这个实体没有在当前的“默认”连接中注册? 打字机

[英]RepositoryNotFoundError: No repository for "User" was found. Looks like this entity is not registered in current "default" connection? Typeorm

I am having a fun issue trying to get TypeOrm to work in my nestjs project.我在尝试让 TypeOrm 在我的 nestjs 项目中工作时遇到了一个有趣的问题。

I have the below code to configure my project, yes everything loads, and yes I am able to connect to my database.我有下面的代码来配置我的项目,是的,一切都加载了,是的,我能够连接到我的数据库。

import { CacheModule, Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { ConfigModule } from '@nestjs/config';
import { AuthenticationController } from './controllers/authentication.controller';
import { AuthenticationService } from './services/authentication.service';
import { Connection } from 'typeorm';
import { BaseEntity } from './entities/base.entity';

@Module({
  imports: [
    ConfigModule.forRoot(),
    TypeOrmModule.forRoot({
        type: 'postgres',
        host: 'localhost',
        port: 5432,
        username: 'postgres',
        password: process.env.POSTGRE_PASSWORD,
        database: process.env.DATABASE,
        migrationsTableName: 'migration_table',
        entities: [User, BaseEntity],
        migrations: [__dirname + '/migrations/**/*.ts'],
        subscribers: [__dirname + '/subscribers/**/*.ts'],
        cli: {
          entitiesDir: '/entitys',
          migrationsDir: '/migrations',
          subscribersDir: '/subscribers',
        },
        synchronize: true,
        autoLoadEntities: true,
    }),
    CacheModule.register(),
    PassportModule,
    JwtModule.register({
      secret: 'myprivatekey',
      signOptions: { expiresIn: '1d' },
    }),
  ],
  controllers: [AuthenticationController],
  providers: [AuthenticationService],
})
export class AppModule {
  constructor(private connection: Connection) {}
}

and here are the entities:以下是实体:

import {
  Column,
  BeforeUpdate,
  BeforeInsert,
} from 'typeorm';

export class BaseEntity {
  @Column()
  created_at: Date;

  @Column({
    default: new Date(),
  })
  updated_at: Date;

  @BeforeUpdate()
  updateUpdatedAt() {
    this.updated_at = new Date();
  }

  @BeforeInsert()
  updateCreatedAt() {
    this.created_at = new Date();
  }
}
import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  Generated,
} from 'typeorm';

import { BaseEntity } from './base.entity';

@Entity('users')
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  @Generated('uuid')
  uuid: string;

  @Column()
  first_name: string;

  @Column()
  last_name: string;

  @Column()
  email: string;

  @Column()
  password: string;

  @Column({
    default: false,
  })
  confirmed: boolean;

  @Column({
    default: null,
  })
  seller_id: string;

  @Column({
    default: null,
  })
  auth_token: string;

  @Column({
    default: false,
  })
  is_admin: boolean;
}

I originally tried doing a glob pattern match, to no avail, so now I am directly importing in my Entities until I can get something to run.我最初尝试进行 glob 模式匹配,但无济于事,所以现在我直接在我的实体中导入,直到我可以运行一些东西。 Also note, that all my modules load prior to the error above and the error is from using the @InjectRepository() decorator within either the AuthenticationController or AdminController.另请注意,我的所有模块都在上述错误之前加载,并且错误来自在 AuthenticationController 或 AdminController 中使用 @InjectRepository() 装饰器。 Everywhere I have looked has said its because my entities are not being loaded, which I am not sure how that is possible.我看过的所有地方都说这是因为我的实体没有被加载,我不确定这是怎么可能的。 Thanks.谢谢。

In my case I had an error on Production mode, to fix it I added the path of the compiled JS files in the build folder.在我的情况下,我在生产模式下遇到错误,为了修复它,我在build文件夹中添加了编译的 JS 文件的路径。

const conn: MongoConnectionOptions = {
  type: 'mongodb',
  url: DB_URL,
  synchronize: true,
  useNewUrlParser: true,
  useUnifiedTopology: true,
  logging: true,
  entities: ['src/entity/*.ts', './build/src/entity/*.js'], // <- Here!
  migrations: ['src/migration/**/*.ts'],
  subscribers: ['src/subscriber/**/*.ts'],
  cli: {
    entitiesDir: 'src/entity',
    migrationsDir: 'src/migration',
    subscribersDir: 'src/subscriber',
  },
  extra: {
    authSource: DB_AUTH_SOURCE,
  },
};

The short version could be: entities: ['**/src/entity/*{.ts,.js}'],简短的版本可能是: entities: ['**/src/entity/*{.ts,.js}'],

Try giving a name to your entity with the @Entity decorator:尝试使用 @Entity 装饰器为您的实体命名:

import { Entity, PrimaryColumn, Column } from "typeorm";
@Entity("category") // <-- Right here

seems like it is, as you said, because the entities are not loaded.正如您所说,似乎是因为实体未加载。

my guess is: the config file you have added tries to find the files at:我的猜测是:您添加的配置文件尝试在以下位置查找文件:

  migrations: [__dirname + '/migrations/**/*.ts'],
  subscribers: [__dirname + '/subscribers/**/*.ts'],

are those entity files in the same dir as the module is?这些实体文件是否与模块位于同一目录中? could help to print the output of those paths just to make sure it is correct.可以帮助打印这些路径的 output 以确保它是正确的。

also note that typescript compiles to javascript, so you might run into the same problem if you run the code from /dist, because it will be able to see only the ".js" compiled files, so i'd suggest to use另请注意,typescript 编译为 javascript,因此如果从 /dist 运行代码,您可能会遇到同样的问题,因为它只能看到“.js”编译文件,所以我建议使用

  migrations: [__dirname + '/migrations/**/*{.ts,.js}'],
  subscribers: [__dirname + '/subscribers/**/*{.ts,.js}'],

if its nothing of the above 2 options, please provide the full routes of the entities and modules in play.如果以上两个选项都不是,请提供实体和模块的完整路线。

I faced the same issue, glob paths don't work in case of monorepo .我遇到了同样的问题,在monorepo的情况下,全局路径不起作用。

Note, however, that glob paths are not supported by webpack , so if you are building your application within a monorepo , you won't be able to use them.但是请注意, webpack 不支持全局路径,因此如果您在monorepo中构建应用程序,您将无法使用它们。 To address this issue, an alternative solution is provided.为了解决这个问题,提供了一种替代解决方案。 To automatically load entities, set the autoLoadEntities property of the configuration object (passed into the forRoot() method).要自动加载实体,请设置配置 object 的 autoLoadEntities 属性(传递给 forRoot() 方法)。

Note that entities that aren't registered through the forFeature() method, but are only referenced from the entity (via a relationship), won't be included by way of the autoLoadEntities setting.请注意,未通过 forFeature() 方法注册但仅从实体引用(通过关系)的实体不会通过 autoLoadEntities 设置包含在内。

-- NestJS Docs -- NestJS 文档

Also, I was using ormconfig.ts , which also presents one more difficulty -另外,我正在使用ormconfig.ts ,这也带来了另一个困难 -

Note that the ormconfig.json file is loaded by the typeorm library.请注意,ormconfig.json 文件由 typeorm 库加载。 Thus, any of the extra properties described above (which are supported internally by way of the forRoot() method - for example, autoLoadEntities and retryDelay) won't be applied.因此,将不会应用上述任何额外属性(通过 forRoot() 方法在内部支持 - 例如,autoLoadEntities 和 retryDelay)。 Luckily, TypeORM provides the getConnectionOptions function that reads connection options from the ormconfig file or environment variables.幸运的是,TypeORM 提供了从 ormconfig 文件或环境变量中读取连接选项的 getConnectionOptions function。 With this, you can still use the configuration file and set Nest-specific options.有了这个,你仍然可以使用配置文件并设置 Nest 特定的选项。

-- NestJS Docs -- NestJS 文档

Final Solution最终解决方案

  1. root/main module -根/主模块 -
import { getConnectionOptions } from 'typeorm';
...
@Module({
  imports: [
   TypeOrmModule.forRootAsync({
    useFactory: async () =>
      Object.assign(await 
       getConnectionOptions(), {
        autoLoadEntities: true,
      }),
    })
   ],
 ...
})
  1. app/child module -应用程序/子模块 -
...
@Module({
  imports: [TypeOrmModule.forFeature([<entities go here>])],
  ...
})
...

In my case, I solved it by declaring the entity in the connection file.就我而言,我通过在连接文件中声明实体来解决它。

The TypeORM documentation explains this change. TypeORM 文档解释了这一变化。

Creating a connection to the database创建到数据库的连接

Now, when our entity is created, let's create an index.ts (or app.ts whatever you call it) file and set up our connection there:现在,当我们的实体被创建时,让我们创建一个 index.ts(或 app.ts 随便你叫什么)文件并在那里建立我们的连接:

import "reflect-metadata";
import { createConnection } from "typeorm";
import { Photo } from "./entity/Photo";

createConnection({
    type: "mysql",
    host: "localhost",
    port: 3306,
    username: "root",
    password: "admin",
    database: "test",
    entities: [
        Photo
    ],
    synchronize: true,
    logging: false
}).then(connection => {
    // here you can start to work with your entities
}).catch(error => console.log(error));

Make sure you put the @ sign in front of your entity decorator (3 of my entities didn't and the error message was related to the relations because it didn't find my entites)确保将 @ 符号放在实体装饰器前面(我的 3 个实体没有,并且错误消息与关系有关,因为它没有找到我的实体)

I had the same problem and I added the following properties in my ormconfig:我有同样的问题,我在我的 ormconfig 中添加了以下属性:

 "cli":{ "migrationsDir":"./src/database/migrations", "entitiesDir": ".src/modules/cars/entities" }, "entities": [ "./src/modules/cars/entities/**/*{.ts,.js}" ]

Works fine to me.对我来说很好。

When reading the source code I realized that the strings are still there (inside the JS bundle), so it is calling something that is just not there as all files are inside of it, I tried importing the models directly within the app.module and not passing strings or patterns to the entities array, but the imported entity classes instead, that worked like a charm.阅读源代码时,我意识到字符串仍然存在(在 JS 包中),所以它调用了一些不存在的东西,因为所有文件都在其中,我尝试直接在 app.module 中导入模型和不是将字符串或模式传递给实体数组,而是导入的实体类,这就像一个魅力。

Given, this may not be the cleanest approach, because you have to write the paths in the imports to different modules and import them one by one.鉴于此,这可能不是最干净的方法,因为您必须将导入中的路径写入不同的模块并一一导入。 It would be great to see what others have to say on how to tackle and improve on this so that we can achieve a cleaner solution.很高兴看到其他人对如何解决和改进这个问题有什么看法,以便我们能够实现更清洁的解决方案。

This works today as of Nov/2021.这适用于今天 2021 年 11 月。

Make sure you annotated the entity class with @Entity()确保您使用 @Entity() 注释了实体 class

Example例子

@Entity() <-- IMPORTANT
export class Tax {
  @PrimaryGeneratedColumn()
  taxId: number;

  @Column({ type: 'varchar', length: 48 })
  name: string;

  @Column({ type: 'varchar', length: 128 })
  description: string;

  @Column({ type: 'smallint' })
  rate: string;
}

Also check your connection, if entities are entities: ['dist/**/*.entity.js'] , make sure your file name is {name}.entity.ts还要检查您的连接,如果实体是entities: ['dist/**/*.entity.js'] ,请确保您的文件名是{name}.entity.ts

in base entity you havent provided decorator @Entity()在基本实体中,您没有提供装饰器 @Entity()

@Entity()
export class BaseEntity {
  @Column()
  created_at: Date;

}

In my case it was because I had the repository inside the list of:就我而言,这是因为我的存储库位于以下列表中:

TypeOrmModule.forFeature([ 
    TblX,
    RepositoryX
]),

Removing RepositoryX from here fixed it.从这里删除 RepositoryX 修复了它。

I had everything correct except the filename.除了文件名,我一切都正确。

It should be like entityname.entity.ts它应该像entityname.entity.ts

But it was like entityname.ts但它就像entityname.ts

you can have this error also in case you register the services in the import statment like this如果您像这样在导入语句中注册服务,也会出现此错误

``` imports: [
        TypeOrmModule.forFeature([
          LevelService
        ])
      ],```

this will throw the same error这将引发相同的错误

If all of the answers above do not work, you could simply just clear and rebuild the dist directory by running the following command如果以上所有答案都不起作用,您只需通过运行以下命令清除并重建dist目录

npm run build

Then, restart your application然后,重新启动您的应用程序

npm run start:dev

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM