TypeORM Entity Metadata not found

Viewed 6963

Heyho,

im trying to build a backend for a type of ecommerce site using NestJS + TypeORM.

i need a m:n relation between my order and products table. Hovever since i need some custom fields within the pivot table i looked up typeorms documentation and as stated there i need to create a new entity which ive done. Now i get an error starting up my NestJS application:

Error: Entity metadata for Product#productToOrders was not found. Check if you specified a correct entity object and if it's connected in the connection options.

My product.entity.ts:

import { BaseEntity, Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { ProductToOrder } from "./productToOrder.entity";

@Entity()
export class Product extends BaseEntity{
    @PrimaryGeneratedColumn()
    id: number;
    
    @Column()
    name: string;
    
    @Column()
    description: string;
    
    @Column()
    price: number;

    @OneToMany(type => ProductToOrder, productToOrder => productToOrder.product)
    productToOrders: ProductToOrder[];
}

My productToOrder.entity.ts

import { Order } from "src/order/order.entity";
import { BaseEntity, Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
import { Product } from "./product.entity";

@Entity()
export class ProductToOrder extends BaseEntity{
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    amount: number;

    @ManyToOne(() => Product, product => product.productToOrders,{eager: false})
    product: Product;

    @ManyToOne(() => Order, order => order.productToOrders, {eager: false})
    order: Order;
}

my order.entity.ts

import { User } from "src/auth/user.entity";
import { Product } from "src/product/product.entity";
import { ProductToOrder } from "src/product/productToOrder.entity";
import { BaseEntity, Column, Entity, JoinTable, ManyToMany, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class Order extends BaseEntity{
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    ordernumber: number;

    @Column()
    totalprice: number;
    
    @ManyToOne(type => User, user => user.orders, {eager: false})
    user_id: User[];

    @OneToMany(() => ProductToOrder, productToOrder => productToOrder.order, {eager: true})
    productToOrders: ProductToOrder[];
}

My directory structure:

src/
├── order
│   ├── order.entity.ts
│   ├── order.module.ts
│   ├── order.service.ts
│   ├── order.controller.ts
│   └── order.repository.ts
├── product
│   ├── product.entity.ts
│   ├── product.module.ts
│   ├── product.service.ts
│   ├── product.controller.ts
│   ├── productToOrder.entity.ts <- i put the entity for the pivot table here, not sure if its right
│   └── product.repository.ts
└── xy

My app.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthModule } from './auth/auth.module';
import { typeOrmConfig } from './config/typeorm.config';
import { ProductModule } from './product/product.module';
import { OrderModule } from './order/order.module';


@Module({
  imports: [
    TypeOrmModule.forRoot(typeOrmConfig),
    AuthModule,
    ProductModule,
    OrderModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

my typeorm.config.ts

import { TypeOrmModuleOptions } from "@nestjs/typeorm";
import * as config from 'config';

const dbConfig = config.get('db');

export const typeOrmConfig: TypeOrmModuleOptions = {
    type: dbConfig.type,
    host: dbConfig.host,
    port: dbConfig.port,
    username: dbConfig.username,
    password: dbConfig.password,
    database: dbConfig.database,
    autoLoadEntities: true,
    synchronize: dbConfig.synchronize,
}

if i add the

entities: ["dist/**/*.entity{.ts,.js}"],

line to my typeorm.config.ts and start the application with npm run start:dev the errorcode changes to

 TypeError: metatype is not a constructor
4 Answers

In your TypeORM config, you must have defined the entities attribute:

TypeOrmModule.forRoot({
  // ...
  entities: ['src/**/*.entity.ts']
})

Check that the pattern also matches your new entity.

okey so the problem wasnt my typeorm config, neither my entities.

The problem was my PassportJS middleware. within my order.controller.ts

looked like this:

import { Body, Controller, Post, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { GetUser } from 'src/auth/get-user.decorator';
import { User } from 'src/auth/user.entity';
import { CreateOrderDto } from './dto/create-order.dto';
import { OrderService } from './order.service';

@Controller('order')
@UseGuards(AuthGuard)
export class OrderController {
    constructor(
        private orderService: OrderService,
    ){}

    @Post()
    @UsePipes(ValidationPipe)
    createProduct(
        @Body(ValidationPipe) createdto: CreateOrderDto,
        @GetUser() user: User,
    ){
        return this.orderService.createOrder(createdto, user);
    }
}

as you can see im missing brackets within the

@UseGuards(AuthGuard)

decorator. What it really shouldve looked like:

@UseGuards(AuthGuard()) //<-- Missing brackets

i found inspiration for this solution right here: https://github.com/nestjs/nest/issues/2399

maybe you not add the ProductToOrder entity to productModule?

@Module({
  imports: [TypeOrmModule.forFeature([Product, ProductToOrder])],
})
export class ProductModule {}

Do you use webpack when build your app? if you do I have the same issue so.. for fix it in a dev mode i put the nest-cli.ts archive like that.

   {
      "$schema": "https://json.schemastore.org/nest-cli",
      "collection": "@nestjs/schematics",
      "sourceRoot": "src",
      "compilerOptions": {
        "webpack": false
      }
    }
Related