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
1 Answer
Reset to default 3First 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.