最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - EntityMetadataNotFound: No metadata for "User" was found - Stack Overflow

programmeradmin5浏览0评论

PS.: I have already read a lot of similar topics, but none of them could fix my issue, already tried changing the regex pattern on entities for ormconfig.js and other stuffs.

Well, a few days ago I was able to execute this ExpressJS app with success, no error was appearing. But now, it just started to throw EntityMetadataNotFound: No metadata for "User" was found..

This is the repository for the project:

As you can see, My entities and migrations points to dist/entities/*.js and dist/database/migrations/*.js respectively, since I've read that TypeORM is not able to use them while in typescript (using ts-node-dev to run the app, if the entities are in .ts, I get errors saying that I can't use imports and stuffs from ES6+ on plain javascript files. And if I run migrations using the .ts files, no migrations are found to run.). Also, you'll see that I have my Entity, Repository, Service and Controller all correct (I can't see any problems with them), but still, I get that error when I try to make an interaction with the database.

Insomnia request body: /POST http://localhost:3000/api/users

{
    "name": "123",
    "password": "123",
    "email": "[email protected]",
    "admin": true
}

response:

{
  "error": {
    "name": "EntityMetadataNotFound",
    "message": "No metadata for \"User\" was found."
  }
}

Error on terminal:

EntityMetadataNotFound: No metadata for "User" was found.
    at new EntityMetadataNotFoundError (C:\Users\joaov\Documents\gittin\src\error\EntityMetadataNotFoundError.ts:10:9)
    at Connection.getMetadata (C:\Users\joaov\Documents\gittin\src\connection\Connection.ts:337:19)
    at EntityManager.getCustomRepository (C:\Users\joaov\Documents\gittin\src\entity-manager\EntityManager.ts:976:86)
    at Connection.getCustomRepository (C:\Users\joaov\Documents\gittin\src\connection\Connection.ts:372:29)
    at Object.getCustomRepository (C:\Users\joaov\Documents\gittin\src\index.ts:298:55)
    at CreateUserService.<anonymous> (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:14:37)
    at step (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:33:23)
    at Object.next (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:14:53)
    at C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:8:71
    at new Promise (<anonymous>)

To make it easier, these are the relevant files that I think. Please tell me if any other file is relevant too:

package.json:

{
  "name": "gittin",
  "version": "1.0.0",
  "main": "./dist/index.js",
  "repository": ".git",
  "author": "Joao Casarin <[email protected]>",
  "license": "MIT",
  "scripts": {
    "db": "docker-pose -f ./docker-pose.db.yml up --build -d",
    "docker:dev": "docker-pose -f ./docker-pose.dev.yml up --build -d",
    "docker:prod": "docker-pose -f ./docker-pose.yml up --build -d",
    "docker:clear": "docker-pose down -v --rmi local",
    "docker:stop": "docker-pose down",
    "dev": "ts-node-dev ./src/index.ts",
    "test": "jest",
    "migration:run": "ts-node-dev ./node_modules/typeorm/cli.js migration:run",
    "migration:create": "ts-node-dev ./node_modules/typeorm/cli.js migration:create",
    "entity:create": "ts-node-dev ./node_modules/typeorm/cli.js entity:create",
    "build": "tsc",
    "start": "node ."
  },
  "dependencies": {
    "axios": "^0.21.1",
    "bcryptjs": "^2.4.3",
    "class-transformer": "^0.4.0",
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "express-async-errors": "^3.1.1",
    "jsonwebtoken": "^8.5.1",
    "pg": "^8.6.0",
    "reflect-metadata": "^0.1.13",
    "typeorm": "^0.2.34",
    "uuid": "^8.3.2"
  },
  "devDependencies": {
    "@types/babel__core": "^7.1.15",
    "@types/bcryptjs": "^2.4.2",
    "@types/cors": "^2.8.10",
    "@types/express": "^4.17.12",
    "@types/jest": "^26.0.23",
    "@types/jsonwebtoken": "^8.5.4",
    "@types/node": "^15.12.4",
    "@types/supertest": "^2.0.11",
    "@types/uuid": "^8.3.1",
    "jest": "^27.0.5",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-node-dev": "^1.1.6",
    "typescript": "^4.3.4"
  }
}

ormconfig.js:

module.exports = {
    "type": "postgres",
    "ssl": process.env.NODE_ENV === 'production'
           && process.env.DATABASE_URL !== 'postgres://postgres:docker@localhost:5432/gittin'
           && process.env.DATABASE_URL !== 'postgres://postgres:docker@db:5432/gittin' ? { rejectUnauthorized: false } : false,

    "url": process.env.DATABASE_URL,
    
    "entities": ["dist/entities/*.js"], // typeorm loads entities from this directory
    "migrations": ["dist/database/migrations/*.js"], // typeorm loads migrations from the directory

    "dropSchema": process.env.NODE_ENV === 'test' ? true : false,
    "migrationsRun": process.env.NODE_ENV !== 'production' ? true : false,

    "cli": {
        "migrationsDir": "src/database/migrations", // typeorm creates migrations in this directory
        "entitiesDir": "src/entities" // typeorm creates entities in this directory
    }
}

src/entities/User.ts:

import { Entity, PrimaryColumn, Column, CreateDateColumn, UpdateDateColumn } from "typeorm";
import { Exclude } from "class-transformer";
import { v4 as uuid } from "uuid";

@Entity("users")
class User {

    @PrimaryColumn()
    readonly id: string;

    @Column()
    name: string;

    @Column()
    email: string;

    @Column()
    admin: boolean;

    @Exclude()
    @Column()
    password: string;

    @CreateDateColumn()
    created_at: Date;

    @UpdateDateColumn()
    updated_at: Date;

    constructor() {
        if (!this.id) {
            this.id = uuid();
        }
    }
}

export { User };

src/repositories/UserRepositories.ts:

import { EntityRepository, Repository } from "typeorm";
import { User } from "../entities/User";

@EntityRepository(User)
class UsersRepositories extends Repository<User> {}

export { UsersRepositories };

src/services/CreateUserService.ts:

import { getCustomRepository } from "typeorm";
import { UsersRepositories } from "../repositories/UsersRepositories";
import { hash } from "bcryptjs";

interface IUserRequest {
    name: string;
    email: string;
    admin?: boolean;
    password: string;
}

class CreateUserService {
    async execute({ name, email, admin = false, password }: IUserRequest) {
            const usersRepository = getCustomRepository(UsersRepositories);

            if(!email) {
                throw new Error('Incorrect e-mail.');
            }

            const userAlreadyExists = await usersRepository.findOne({ email });

            if(userAlreadyExists) {
                throw new Error('User already exists.');
            }

            const passwordHash = await hash(password, 8);

            const user = usersRepository.create({ name, email, admin, password: passwordHash });

            await usersRepository.save(user);

            return user;
    }
}

export { CreateUserService };

src/controllers/CreateUserController.ts:

import { Request, Response } from "express";
import { CreateUserService } from "../services/CreateUserService";

class CreateUserController {
    async handle(request: Request, response: Response) {
        try {
            const { name, email, admin, password } = request.body;

            const createUserService = new CreateUserService();

            const user = await createUserService.execute({ name, email, admin, password });

            return response.send(user);
        } catch (error) {
            return response.send({ error });
        }
    }
}

export { CreateUserController };

src/routes/index.ts:

import { Router, Request, Response, NextFunction } from "express";
import { CreateUserController } from "../controllers/CreateUserController";

const router = Router();

const createUserController = new CreateUserController();
router.post('/users', createUserController.handle);

export default router;

PS.: I have already read a lot of similar topics, but none of them could fix my issue, already tried changing the regex pattern on entities for ormconfig.js and other stuffs.

Well, a few days ago I was able to execute this ExpressJS app with success, no error was appearing. But now, it just started to throw EntityMetadataNotFound: No metadata for "User" was found..

This is the repository for the project: https://github./joaocasarin/gittin

As you can see, My entities and migrations points to dist/entities/*.js and dist/database/migrations/*.js respectively, since I've read that TypeORM is not able to use them while in typescript (using ts-node-dev to run the app, if the entities are in .ts, I get errors saying that I can't use imports and stuffs from ES6+ on plain javascript files. And if I run migrations using the .ts files, no migrations are found to run.). Also, you'll see that I have my Entity, Repository, Service and Controller all correct (I can't see any problems with them), but still, I get that error when I try to make an interaction with the database.

Insomnia request body: /POST http://localhost:3000/api/users

{
    "name": "123",
    "password": "123",
    "email": "[email protected]",
    "admin": true
}

response:

{
  "error": {
    "name": "EntityMetadataNotFound",
    "message": "No metadata for \"User\" was found."
  }
}

Error on terminal:

EntityMetadataNotFound: No metadata for "User" was found.
    at new EntityMetadataNotFoundError (C:\Users\joaov\Documents\gittin\src\error\EntityMetadataNotFoundError.ts:10:9)
    at Connection.getMetadata (C:\Users\joaov\Documents\gittin\src\connection\Connection.ts:337:19)
    at EntityManager.getCustomRepository (C:\Users\joaov\Documents\gittin\src\entity-manager\EntityManager.ts:976:86)
    at Connection.getCustomRepository (C:\Users\joaov\Documents\gittin\src\connection\Connection.ts:372:29)
    at Object.getCustomRepository (C:\Users\joaov\Documents\gittin\src\index.ts:298:55)
    at CreateUserService.<anonymous> (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:14:37)
    at step (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:33:23)
    at Object.next (C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:14:53)
    at C:\Users\joaov\Documents\gittin\src\services\CreateUserService.ts:8:71
    at new Promise (<anonymous>)

To make it easier, these are the relevant files that I think. Please tell me if any other file is relevant too:

package.json:

{
  "name": "gittin",
  "version": "1.0.0",
  "main": "./dist/index.js",
  "repository": "https://github./joaocasarin/gittin.git",
  "author": "Joao Casarin <[email protected]>",
  "license": "MIT",
  "scripts": {
    "db": "docker-pose -f ./docker-pose.db.yml up --build -d",
    "docker:dev": "docker-pose -f ./docker-pose.dev.yml up --build -d",
    "docker:prod": "docker-pose -f ./docker-pose.yml up --build -d",
    "docker:clear": "docker-pose down -v --rmi local",
    "docker:stop": "docker-pose down",
    "dev": "ts-node-dev ./src/index.ts",
    "test": "jest",
    "migration:run": "ts-node-dev ./node_modules/typeorm/cli.js migration:run",
    "migration:create": "ts-node-dev ./node_modules/typeorm/cli.js migration:create",
    "entity:create": "ts-node-dev ./node_modules/typeorm/cli.js entity:create",
    "build": "tsc",
    "start": "node ."
  },
  "dependencies": {
    "axios": "^0.21.1",
    "bcryptjs": "^2.4.3",
    "class-transformer": "^0.4.0",
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "express-async-errors": "^3.1.1",
    "jsonwebtoken": "^8.5.1",
    "pg": "^8.6.0",
    "reflect-metadata": "^0.1.13",
    "typeorm": "^0.2.34",
    "uuid": "^8.3.2"
  },
  "devDependencies": {
    "@types/babel__core": "^7.1.15",
    "@types/bcryptjs": "^2.4.2",
    "@types/cors": "^2.8.10",
    "@types/express": "^4.17.12",
    "@types/jest": "^26.0.23",
    "@types/jsonwebtoken": "^8.5.4",
    "@types/node": "^15.12.4",
    "@types/supertest": "^2.0.11",
    "@types/uuid": "^8.3.1",
    "jest": "^27.0.5",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-node-dev": "^1.1.6",
    "typescript": "^4.3.4"
  }
}

ormconfig.js:

module.exports = {
    "type": "postgres",
    "ssl": process.env.NODE_ENV === 'production'
           && process.env.DATABASE_URL !== 'postgres://postgres:docker@localhost:5432/gittin'
           && process.env.DATABASE_URL !== 'postgres://postgres:docker@db:5432/gittin' ? { rejectUnauthorized: false } : false,

    "url": process.env.DATABASE_URL,
    
    "entities": ["dist/entities/*.js"], // typeorm loads entities from this directory
    "migrations": ["dist/database/migrations/*.js"], // typeorm loads migrations from the directory

    "dropSchema": process.env.NODE_ENV === 'test' ? true : false,
    "migrationsRun": process.env.NODE_ENV !== 'production' ? true : false,

    "cli": {
        "migrationsDir": "src/database/migrations", // typeorm creates migrations in this directory
        "entitiesDir": "src/entities" // typeorm creates entities in this directory
    }
}

src/entities/User.ts:

import { Entity, PrimaryColumn, Column, CreateDateColumn, UpdateDateColumn } from "typeorm";
import { Exclude } from "class-transformer";
import { v4 as uuid } from "uuid";

@Entity("users")
class User {

    @PrimaryColumn()
    readonly id: string;

    @Column()
    name: string;

    @Column()
    email: string;

    @Column()
    admin: boolean;

    @Exclude()
    @Column()
    password: string;

    @CreateDateColumn()
    created_at: Date;

    @UpdateDateColumn()
    updated_at: Date;

    constructor() {
        if (!this.id) {
            this.id = uuid();
        }
    }
}

export { User };

src/repositories/UserRepositories.ts:

import { EntityRepository, Repository } from "typeorm";
import { User } from "../entities/User";

@EntityRepository(User)
class UsersRepositories extends Repository<User> {}

export { UsersRepositories };

src/services/CreateUserService.ts:

import { getCustomRepository } from "typeorm";
import { UsersRepositories } from "../repositories/UsersRepositories";
import { hash } from "bcryptjs";

interface IUserRequest {
    name: string;
    email: string;
    admin?: boolean;
    password: string;
}

class CreateUserService {
    async execute({ name, email, admin = false, password }: IUserRequest) {
            const usersRepository = getCustomRepository(UsersRepositories);

            if(!email) {
                throw new Error('Incorrect e-mail.');
            }

            const userAlreadyExists = await usersRepository.findOne({ email });

            if(userAlreadyExists) {
                throw new Error('User already exists.');
            }

            const passwordHash = await hash(password, 8);

            const user = usersRepository.create({ name, email, admin, password: passwordHash });

            await usersRepository.save(user);

            return user;
    }
}

export { CreateUserService };

src/controllers/CreateUserController.ts:

import { Request, Response } from "express";
import { CreateUserService } from "../services/CreateUserService";

class CreateUserController {
    async handle(request: Request, response: Response) {
        try {
            const { name, email, admin, password } = request.body;

            const createUserService = new CreateUserService();

            const user = await createUserService.execute({ name, email, admin, password });

            return response.send(user);
        } catch (error) {
            return response.send({ error });
        }
    }
}

export { CreateUserController };

src/routes/index.ts:

import { Router, Request, Response, NextFunction } from "express";
import { CreateUserController } from "../controllers/CreateUserController";

const router = Router();

const createUserController = new CreateUserController();
router.post('/users', createUserController.handle);

export default router;
Share Improve this question asked Aug 3, 2021 at 20:51 João CasarinJoão Casarin 9362 gold badges17 silver badges29 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

First of all, your git repo was very helpful to find the issue. You just need to update your ormconfig.js file like below:

module.exports = {
    ...
    "entities": ["src/entities/*{.js,.ts}"], // typeorm loads entities from this directory
    ...
    }
}

I only tested for npm run dev and it is using ts-node-dev to execute your files.

Maybe you might have to change this when it is piled and run in the production.

发布评论

评论列表(0)

  1. 暂无评论