Driftminder
Driftminder

Reputation: 31

NestJS / TypeORM - Metadata for "" was not found

I'm struggling a bit with NestJS because i can't use 2 on 3 .entities.ts file.

I have 1 file working without any problems.

When i tried a this.xxxrepositories.find(); i got the error

Very strange information : when i do a synchronized: true on app.module.ts, it create correctly the both table in my dev database

So : How can it can't found metadata if it can create the tables ?

Here the code :

app.module.ts

import { Module } from '@nestjs/common';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { ScheduleModule } from '@nestjs/schedule';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Races } from './models/races.entities';
import { Ticket } from './models/ticket.entities';
import { Track } from './models/track.entities';
import { SynchronizedModule } from './synchronized/synchronized.module';
import { TicketController } from './ticket/ticket.controller';
import { TicketModule } from './ticket/ticket.module';
import { WebsocketModule } from './websocket/websocket.module';

@Module({
  imports: [TicketModule, WebsocketModule,
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.DATABASE_HOST,
      port: 3306,
      username: process.env.DATABASE_PUBLIC_LOGIN,
      password: process.env.DATABASE_PUBLIC_PASSWORD,
      database: 'racecontrol-public',
      entities: [Races, Ticket, Track],
    }), TypeOrmModule.forFeature([Races, Ticket, Track]),
    JwtModule.register({
      global: true,
      secret: "f9RexYqCpwoMDR5FJACb",
      signOptions: { expiresIn: '2m' },
      
    }),
    SynchronizedModule,
    ScheduleModule.forRoot(),
  ],
  controllers: [AppController, TicketController],
  providers: [AppService, JwtService],
})
export class AppModule {
  
 }

synchronized.module.ts

import { Logger, Module, OnModuleInit } from '@nestjs/common';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { InjectRepository, TypeOrmModule } from '@nestjs/typeorm';
import axios from 'axios';
import { Repository } from 'typeorm';
import { Races } from '../models/races.entities';
import { Ticket } from '../models/ticket.entities';
import { Track } from '../models/track.entities';

@Module({
  imports: [
    TypeOrmModule.forFeature([Races, Ticket, Track]),
    JwtModule.register({
      global: true,
      secret: "",
      signOptions: { expiresIn: '2m' },
      
    }),
  ],
  controllers: [],
  providers: [JwtService],
  exports: [SynchronizedModule]
})
export class SynchronizedModule implements OnModuleInit {

  constructor(
    private jwtService: JwtService,
    @InjectRepository(Races)
    private readonly racesRepository: Repository<Races>,
    @InjectRepository(Track)
    private readonly tracksRepository: Repository<Track>,

    @InjectRepository(Ticket)
    private readonly ticketsRepository: Repository<Ticket>,
  ) {

  }
  async onModuleInit() {

    const publicTick = await this.ticketsRepository.find(); <= No problem
    const publicRace = await this.racesRepository.find(); <= Metadata not found
    const publicTrack = await this.tracksRepository.find(); <= Metadata not found

   
  }
 }

I give you my .entities file too :

ticket.entities.ts (Functionnal table)


import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity({ name: 'Ticket' })
export class Ticket {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    victim: string;

    @Column()
    accused: string;

    @Column()
    lap: string;

    @Column()
    sector: string;

    @Column()
    corner: string;

    @Column()
    infractionTime: string

    @Column()
    offense: string

    @Column()
    penalty: string

    @Column()
    createdAt: string;

    @Column()
    specifyField: string;

    @Column()
    raceId: number;


}

races.entities.ts (Unfunctionnal file)

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity({ name: 'Races' })
export class Races {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    eventName: string;

    @Column()
    track: string;

    @Column()
    date: string;

    @Column()
    hours: string;

    @Column({
        default: false
    })
    isEntrylistExist: boolean;

    @Column()
    fk_id_track: number;

    @Column()
    createdAt: Date;
}

I've tried :

I really don't understand why in this specific case it cause this error and not on another module from my monorepo ?

[EDIT] More information :

I've seen i have the same problems with another api gateway in my project.

I've change the way i working recently going from local dev to remote server in devcontainer.

I've think about a problem with permission due to devcontainer like cannot access the file, but i've found this in the main.js file generated by NX when using serve:developement :

var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Races = void 0;
const tslib_1 = __webpack_require__(1);
const typeorm_1 = __webpack_require__(32);
let Races = class Races {
};
exports.Races = Races;
tslib_1.__decorate([
    (0, typeorm_1.PrimaryGeneratedColumn)(),
    tslib_1.__metadata("design:type", Number)
], Races.prototype, "id", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)(),
    tslib_1.__metadata("design:type", String)
], Races.prototype, "eventName", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)(),
    tslib_1.__metadata("design:type", String)
], Races.prototype, "track", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)(),
    tslib_1.__metadata("design:type", String)
], Races.prototype, "date", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)(),
    tslib_1.__metadata("design:type", String)
], Races.prototype, "hours", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)({
        default: false
    }),
    tslib_1.__metadata("design:type", Boolean)
], Races.prototype, "isEntrylistExist", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)(),
    tslib_1.__metadata("design:type", Number)
], Races.prototype, "fk_id_track", void 0);
tslib_1.__decorate([
    (0, typeorm_1.Column)(),
    tslib_1.__metadata("design:type", typeof (_a = typeof Date !== "undefined" && Date) === "function" ? _a : Object)
], Races.prototype, "createdAt", void 0);
exports.Races = Races = tslib_1.__decorate([
    (0, typeorm_1.Entity)({ name: 'Races' })
], Races);

This show me that the build have include all the metadata for being use isn't it ?

[EDIT 2] More information

I've tried to create a new microservice with NX console, and this one, can access to this meta with the same call than my APIs ?! this is absolulty non-sens...

Upvotes: 3

Views: 46

Answers (1)

Lajos Arpad
Lajos Arpad

Reputation: 76953

The error message says that it couldn't find the metadata for "", so it is clear that it is searches for metadata for empty string, which is why it cannot find it.

Here's an article for troubleshooting this error type: https://medium.com/@JorgeSantanaDeveloper/troubleshooting-the-no-metadata-was-found-error-in-typeorm-2fab1003b099

  • it suggests checking the database connection, which is clearly not the problem in your case
  • it suggests for checking for entity decorators, such as @Column, @Entity and @PrimaryGeneratedColumn which seems to be properly set
  • it suggests the checking for tsconfig.json, particularly to make sure that emitDecoratorMetadata and experimentalDecorators are both set to true among the compilerOptions, which are likely true in your case, given the fact that metadata was properly found for tick
  • it suggests to double-check the entity naming and file structure. I may add that you need to make sure that your entity files are owned by the same OS user, particularly the user who executes them, AND likely the same privileges
  • if multiple directories are being used for entities, make sure that you are importing and registering them correctly at app.ts and index.ts
  • it suggests that you need to detect and eliminate circular dependencies
  • double-check your entities and migrations paths

The error strongly suggests that your entities whose metadata was not found were not imported correctly or did not have the proper decorators.

Upvotes: 1

Related Questions