RepositoryNotFoundError: репозиторий для «Пользователя» не найден. Похоже, этот объект не зарегистрирован в текущем соединении «по умолчанию»? Typeorm

#node.js #postgresql #nestjs #typeorm

#node.js #postgresql #nestjs #typeorm

Вопрос:

У меня возникла забавная проблема, когда я пытаюсь заставить TypeORM работать в моем проекте nestjs.

У меня есть приведенный ниже код для настройки моего проекта, да, все загружается, и да, я могу подключиться к своей базе данных.

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

и вот сущности:

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

Изначально я пытался выполнить сопоставление с шаблоном глобуса, но безрезультатно, поэтому теперь я напрямую импортирую свои объекты, пока не смогу что-то запустить. Также обратите внимание, что все мои модули загружаются до приведенной выше ошибки, и ошибка связана с использованием декоратора @InjectRepository() либо в AuthenticationController, либо в AdminController. Везде, где я смотрел, говорилось, что это потому, что мои объекты не загружаются, и я не уверен, как это возможно. Спасибо.

Ответ №1:

В моем случае у меня была ошибка в рабочем режиме, чтобы исправить ее, я добавил путь к скомпилированным JS-файлам в build папке.

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

Короткая версия может быть: entities: ['**/src/entity/*{.ts,.js}'],

Ответ №2:

Попробуйте присвоить имя вашему объекту с помощью декоратора @Entity:

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

Комментарии:

1. Да .. это работает.

Ответ №3:

похоже, что это так, как вы сказали, потому что объекты не загружены.

я предполагаю: добавленный вами конфигурационный файл пытается найти файлы по адресу :

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

находятся ли эти файлы объектов в том же каталоге, что и модуль? может помочь распечатать выходные данные этих путей, чтобы убедиться, что они правильные.

также обратите внимание, что typescript компилируется в javascript, поэтому вы можете столкнуться с той же проблемой, если запустите код из / dist, потому что он сможет видеть только скомпилированные файлы «.js», поэтому я бы посоветовал использовать

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

если нет ничего из вышеперечисленных 2 вариантов, пожалуйста, укажите полные маршруты объектов и модулей в игре.

Ответ №4:

Я столкнулся с той же проблемой, глобальные пути не работают в случае monorepo .

Однако обратите внимание, что глобальные пути не поддерживаются webpack, поэтому, если вы создаете свое приложение в monorepo, вы не сможете их использовать. Для решения этой проблемы предлагается альтернативное решение. Чтобы автоматически загружать объекты, установите свойство autoLoadEntities объекта конфигурации (передается в метод forRoot()).).

Обратите внимание, что объекты, которые не зарегистрированы с помощью метода Forforcature(), но на которые ссылаются только из объекта (через связь), не будут включены с помощью параметра autoLoadEntities.

NestJS Docs

Кроме того, я использовал ormconfig.ts , что также представляет еще одну трудность —

Обратите внимание, что файл ormconfig.json загружается библиотекой typeorm. Таким образом, любое из дополнительных свойств, описанных выше (которые поддерживаются внутренне с помощью метода forRoot() — например, autoLoadEntities и retryDelay), применяться не будут. К счастью, TypeORM предоставляет функцию getConnectionOptions, которая считывает параметры подключения из файла ormconfig или переменных среды. При этом вы все равно можете использовать файл конфигурации и устанавливать параметры, зависящие от гнезда.

NestJS Docs

Окончательное решение

  1. корневой / основной модуль —
 import { getConnectionOptions } from 'typeorm';
...
@Module({
  imports: [
   TypeOrmModule.forRootAsync({
    useFactory: async () =>
      Object.assign(await 
       getConnectionOptions(), {
        autoLoadEntities: true,
      }),
    })
   ],
 ...
})
 
  1. приложение / дочерний модуль —
 ...
@Module({
  imports: [TypeOrmModule.forFeature([<entities go here>])],
  ...
})
...
 

Комментарии:

1. Спасибо, это помогло мне. Я также использую monorepo.

Ответ №5:

В моем случае я решил это, объявив объект в файле подключения.

Документация TypeORM объясняет это изменение.

Создание подключения к базе данных

Теперь, когда наша сущность создана, давайте создадим файл 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));
 

Ответ №6:

Убедитесь, что вы поставили знак @ перед вашим декоратором объекта (3 из моих объектов этого не сделали, и сообщение об ошибке было связано с отношениями, потому что оно не нашло мои объекты)

Ответ №7:

У меня была такая же проблема, и я добавил следующие свойства в свой ormconfig:

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

Для меня все работает нормально.

Ответ №8:

При чтении исходного кода я понял, что строки все еще там (внутри пакета JS), поэтому он вызывает что-то, чего просто нет, поскольку все файлы находятся внутри него, я попытался импортировать модели непосредственно в app.module и не передавать строки или шаблоны в массив сущностей,но вместо этого импортированные классы сущностей сработали как шарм.

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

Это работает сегодня по состоянию на ноябрь / 2021.

Ответ №9:

Также проверьте ваше соединение, если объекты есть entities: ['dist/**/*.entity.js'] , убедитесь, что ваше имя файла {name}.entity.ts

Ответ №10:

в базовом объекте вы не указали декоратор @Entity()

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

}
 

Ответ №11:

В моем случае это было потому, что у меня был репозиторий внутри списка:

 TypeOrmModule.forFeature([ 
    TblX,
    RepositoryX
]),
 

Удаление RepositoryX отсюда исправило это.

Ответ №12:

У меня все было правильно, кроме имени файла.

Это должно быть похоже entityname.entity.ts

Но это было похоже entityname.ts

Ответ №13:

Если все приведенные выше ответы не работают, вы можете просто очистить и перестроить dist каталог, выполнив следующую команду

 npm run build
 

Затем перезапустите приложение

 npm run start:dev
 

Комментарии:

1. Это ничего не решит