ripper234
ripper234

Reputation: 230296

No metadata for "User" was found using TypeOrm

I'm trying to get a basic setup working using TypeORM, and getting this error following the setup.

Here is a REPL (just do yarn install && yarn db:dev followed by yarn db:migrate && yarn start to reproduce the error)

Inserting a new user into the database...
{ EntityMetadataNotFound: No metadata for "User" was found.
    at new EntityMetadataNotFoundError (/Users/admin/work/typeorm-naming-strategy/src/error/EntityMetadataNotFoundError.ts:9:9)
    at Connection.getMetadata (/Users/admin/work/typeorm-naming-strategy/src/connection/Connection.ts:313:19)
    at /Users/admin/work/typeorm-naming-strategy/src/persistence/EntityPersistExecutor.ts:77:55
    at Array.forEach (<anonymous>)
    at EntityPersistExecutor.<anonymous> (/Users/admin/work/typeorm-naming-strategy/src/persistence/EntityPersistExecutor.ts:71:30)
    at step (/Users/admin/work/typeorm-naming-strategy/node_modules/typeorm/persistence/EntityPersistExecutor.js:32:23)
    at Object.next (/Users/admin/work/typeorm-naming-strategy/node_modules/typeorm/persistence/EntityPersistExecutor.js:13:53)
    at /Users/admin/work/typeorm-naming-strategy/node_modules/typeorm/persistence/EntityPersistExecutor.js:7:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/admin/work/typeorm-naming-strategy/node_modules/typeorm/persistence/EntityPersistExecutor.js:3:12)
  name: 'EntityMetadataNotFound',
  message: 'No metadata for "User" was found.' }

Upvotes: 69

Views: 168733

Answers (30)

RicardoPHP
RicardoPHP

Reputation: 574

I already knew the points in this thread by heart, but it still took me a while to realize my mistake, so I thought it would be cool to do a step-by-step guide to identify the problem... if anyone identifies another item that could generate this problem, edit the message or reply to it to add it. So here is "Everything that could be happening to generate the error No metadata found" (trying to make the list from the simplest to the most complex error):

  1. Check Entity File Extension in Configuration
  • Ensure that entities in the configuration can read both .ts and .js files by setting it to entities: [__dirname + '/../**/*.entity.{js,ts}'].
  1. Verify Entity Paths
  • Confirm that entity paths are correct, pointing to the dist folder if files are transpiled.
  • Especially if you are using TypeScript, I recommend using the direct class declaration (this way you have more control over who is being referenced and when) instead of making the open declaration using masks like *.ts or *.js;
  1. Include the entity in Module Imports
  • In app.module.ts (or equivalent), include the entities explicitly, e.g., entities: [User].

3.1) Declare entity at forFeature

  • The entity class must be present in the forFeature method call of the TypeOrmModule class. If you are using NestJS with modules, this forFeature call must be present in an imports attribute of the Module decorator, either in the module file (e.g.: UserModule) or in the app module (e.g.: AppModule);
  1. Call initialize() on DataSource
  • If using DataSource, ensure you call initialize() before accessing entities.If you are using an old typeorm version then you may consider use connect method after initilize
  1. Add @Entity() Decorator to Classes
  • Check that the @Entity() decorator is present on all entity classes.
  1. Set autoLoadEntities to True
  • In the configuration, add autoLoadEntities: true to automatically load entities.
  1. Check Database Connection Initialization
  • Ensure the database connection is established before using entities, and AppDataSource.initialize() is awaited if necessary.
  1. Clear dist/ Folder and Rebuild
  • Clear the dist/ folder, especially if using NestJS, to avoid outdated compiled files.
  1. Ensure Unique Entity Names
  • Avoid duplicate entity names;
  • Pay attention to files with mismatched casing, like Billinginfo vs. BillingInfo.
  1. Avoid Conflicting Configuration Files
  • Remove unnecessary files, like both ormconfig.json and ormconfig.ts, to avoid confusion.
  • If you project makes use of both try to stick with only one and if that is not possible be sure to be loading the correct one in the moment you are issuing the error while trying to use the entity;
  1. Verify database columns in entity class match table schema
  • Check that the entity’s fields align with the database table's schema and that the entity declared name in the code is actually the same as the database repository.
  1. Use the correct DataSource (this was the case I was running into this time)
  • If you are accessing it through QueryRunner, check if it is declared in the data-source related to the QueryRunner. In the event that we have more than one data-source, it is common to use one QueryRunner to access some tables and another for other tables, so you may be using the wrong data-source. e.g. In my case I have logDataSource and dataSource, the class I was trying to use was at dataSource and I was using the logDataSource QueryRunner;
  1. Handle Migrations Properly in NestJS
  • For migrations in NestJS, set them outside the module's options if using TypeOrmModuleAsyncOptions.
  1. Update TypeORM Version
  • Sometimes, updating TypeORM to the latest version resolves compatibility issues.

Hope to help someone (or myself in the next time). Cheers

Upvotes: 2

ozkary
ozkary

Reputation: 2704

The way to import the schema definition using JS is by using the EntitySchema class. So, if you have a separate file make sure to include this in the file:

const { EntitySchema } = require('typeorm');

module.exports = new EntitySchema({
    "name": "telemetry",
    "columns": {
        "telemetryId": {
            "primary": true,
            "type": "int",
            "generated": true
        },
...

If you want to use inline code, you can use this syntax to import the file:

const connConfig = {
    ...
        "entities":[
            new EntitySchema(require("../models/entity/telemetry"))
        ],
        "extra": {
            "encrypt": false, 
            "trustServerCertificate": true
        }
    }

Upvotes: 0

sohail-turk
sohail-turk

Reputation: 21

i think you forgot to include @Entity() decorator on top of your entity class. I had the same issue and it was fixed by adding it.

Upvotes: 1

Jorge Santana
Jorge Santana

Reputation: 117

"No Metadata" error on TypeORM could be a LOT of causes. But in most of the cases the Entity was writen wrong or the database connection is not being succesful. I wrote this article trying to cover most of the cases.

Upvotes: 1

Fernando Gurgel
Fernando Gurgel

Reputation: 31

My code was working, but the issue arose for just one function. It is a REST express server.

The problem is that I performed a specific DB operation before the Database was initialized. That action was automatically triggered as soon as the server was up.

So if you have found no solution so far, it can just be a timing issue.

Upvotes: 2

Elton Cavele
Elton Cavele

Reputation: 51

for the new version of typeORM you must register the entity folder and the file extension

export const AppDataSource = new DataSource({
  entities: ["dirname/**.ts"],
});

in the example I used ts, but you can switch to js if that's your case.

in case you use the ormconfig file

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

Upvotes: 5

Mauricio Crecencio
Mauricio Crecencio

Reputation: 1

After a such few google it, I found a specific solution for using TypeORM inside tests (in my case Mocha and Chai).

I was troubling the same error 'No metadata for "x" was found...'

Basically I noticed that sometimes this error doesn't popped up when running tests.

So my solution for it is:

beforeEach(done => setTimeout(done, 500));

Upvotes: -1

Muzuri
Muzuri

Reputation: 583

The problem is on ormConfig

Please try to use this:

entities: [__dirname + '/../**/*.entity.{js,ts}']

Upvotes: 48

andrej28
andrej28

Reputation: 19

In my case problem was not properly initialised apollo server I had to export this function:

export async function startApolloServer() {
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers,
});
await server.start();

server.applyMiddleware({ app });

app.use((req: any, res: any) => {
res.status(200);
res.send("Hello!");
res.end();
});

await new Promise((resolve) => app.listen({ port: 4001 }, resolve));
console.log(`🚀 Server ready at 
http://localhost:4001${server.graphqlPath}`);
return { server, app };
}

and call it in my index.ts file

AppDataSource.initialize()
.then(async () => {
startApolloServer();
})
.catch((error) => console.log(error));

Upvotes: 0

ibnsulaimaan
ibnsulaimaan

Reputation: 21

I had the same issue, I used this: autoLoadEntities: true, in the config file instead of: entities: [__dirname + '/..//.entity.{js,ts}'],*** as seen in this github link: https://github.com/nestjs/nest/blob/master/sample/05-sql-typeorm/src/app.module.ts

Upvotes: 2

Mustapha Khial
Mustapha Khial

Reputation: 132

if you get "Error: No metadata for Quiz was found" because different version. Here is my solution:

  • quiz.module.ts: imports: [TypeOrmModule.forFeature([Quiz])],
  • quiz.service.ts: constructor(@InjectRepository(Quiz) private quizRepository: Repository){}

I dont need quiz.repository.ts file ---- from a youtube comment and the solution worked for me.

Upvotes: 0

Aaron Ullal
Aaron Ullal

Reputation: 5245

For me the only way of having the entities folder work in NestJS + TypeOrm v 0.3.11 was the following configuration:

const typeOrmConfig: TypeOrmModuleOptions = {
  type: 'postgres',
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT, 10),
  name: process.env.DB_NAME,
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  migrations: ['dist/migrations/*.{ts,js}', 'src/migrations/*.{ts,js}'],
  entities: ['dist/entities/*.entity.{ts,js}', 'src/entities/*.entity.{ts,js}'],
  migrationsRun: true,
  autoLoadEntities: true,
};

Upvotes: 1

Alexandr Kostrov
Alexandr Kostrov

Reputation: 121

Try this one. Should never fall

DB_ENTITIES=[dist/**/*.entity.js]

Upvotes: 0

Khushal Vyas
Khushal Vyas

Reputation: 434

I was facing a similar issue, in my case I was using NestJS version 9.0.0.

In app.module while importing typeORM module, one of the properties autoLoadEntities was turned to false. So locally when I was trying to connect to DB, it was throwing me this error while writing a find() query.

Correct way to import typeORM:

    TypeOrmModule.forRoot({
        type: 'mongodb',
        host: process.env.DB_HOST || 'localhost',
        port: parseInt(process.env.DB_PORT) || 27017,
        username: process.env.DB_USERNAME,
        password: process.env.DB_PASSWORD,
        database: process.env.DB_DATABASE,
        ssl: false,
        autoLoadEntities: true,
        synchronize: true,
        logging: true,
    }),

Upvotes: 2

Dura
Dura

Reputation: 83

Besides the @Entity() annotation, with typeorm version 0.3.0 and above also don't forget to put all your entities into your DataSource:

export const dataSource = new DataSource({
    type: "sqlite",
    database: 'data/my_database.db',
    entities: [User],
    ...
    ...
})

https://github.com/typeorm/typeorm/blob/master/CHANGELOG.md#030-2022-03-17

Upvotes: 1

Victor Souto
Victor Souto

Reputation: 330

in my case, i was changing one EmployeeSchema to EmployeeEntity, but i forgot the entity annotation on it:

@Entity()
export class Employee {

Upvotes: 14

Nisal Gunawardana
Nisal Gunawardana

Reputation: 1455

I got the same issue and later found I haven't call the functionality to connect the DB. Just by calling the connection fixed my issue.

    export const AppDataSource = new DataSource({
      type: 'mysql',
      host: process.env.MYSQL_HOST,
      ....
    
    });
    
    
    let dataSource: DataSource;
    
    export const ConnectDb = async () => {
        dataSource = await AppDataSource.initialize();

And use this to connect in your function.

Another occasion I got a similar message when I run $ npm test without properly mocking Jest.spyOn() method and fixed it by:

jest.spyOn(db, 'MySQLDbCon').mockReturnValueOnce(Promise.resolve());
const updateResult = {}
as UpdateResult;
jest.spyOn(db.SQLDataSource, 'getRepository').mockReturnValue({
    update: jest.fn().mockResolvedValue(updateResult),
  }
  as unknown as Repository < unknown > );

Upvotes: 3

Lucas Fell
Lucas Fell

Reputation: 21

Using TypeORM with NestJS, for me the issue was that I was setting the migrations property of the TypeOrmModuleOptions object for the TypeOrmModuleAsyncOptions useFactory method, when instead I should've only set it on the migrations config, which uses the standard TypeORM DataSource type.

This is what I ended up with:

typeorm.config.ts

import { DataSource } from 'typeorm';
import {
  TypeOrmModuleAsyncOptions,
  TypeOrmModuleOptions,
} from '@nestjs/typeorm';

const postgresDataSourceConfig: TypeOrmModuleOptions = {
  ...
  // NO migrations property here
  // Had to add this as well
  autoLoadEntities: true,
  ...
};

export const typeormAsyncConfig: TypeOrmModuleAsyncOptions = {
  useFactory: async (): Promise<TypeOrmModuleOptions> => {
    return postgresDataSourceConfig;
  },
};

// Needed to work with migrations, not used by NestJS itself
export const postgresDataSource = new DataSource({
  ...postgresDataSourceConfig,
  type: 'postgres',
  // Instead use it here, because the TypeORM Nest Module does not care for migrations
  // They must be done outside of NestJS entirely
  migrations: ['src/database/migrations/*.ts'],
});

migrations.config.ts

import { postgresDataSource } from './typeorm.config';

export default postgresDataSource;

And the script to run TypeORM CLI was

"typeorm-cli": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli -d ./src/database/migrations.config.ts"

Upvotes: 0

DanielHefti
DanielHefti

Reputation: 344

In my case I've provided a wrong db password. Instead of receiving an error message like "connection to db failed" I've got the error message below.

EntityMetadataNotFound: No metadata for "User" was found.

Upvotes: 0

Tiago
Tiago

Reputation: 732

For me it was two things, while using it with NestJS:

  • There was two entities with the same name (but different tables)

Once I fixed it, the error still happened, then I got to point two:

  • Delete the dist/build directory

Not sure how the build process works for typeorm, but once I deleted that and ran the project again it worked. Seems like it was not updating the generated files.

Upvotes: 0

小歌迷
小歌迷

Reputation: 151

ForMe , i have set error path cause this problem

my error code like this

enter image description here

and then i check the entities path . i modify the path to correct. then the typeorm working

enter image description here

Upvotes: 2

This error can also come up if you have a nodemon.json file in your project.

So after including your entity directory for both build and dev in the entities array

export const AppDataSource = new DataSource({
type: 'mysql',
host: DB_HOST_DEV,
port: Number(DB_PORT),
username: DB_USER_DEV,
password: DB_PASSWORD_DEV,
database: DB_NAME_DEV,
synchronize: false,
logging: false,
entities: [ 
    process.env.NODE_ENV === "prod"
    ? "build/entity/*{.ts,.js}"
    : "src/entity/*{.ts,.js}",
],
migrations: ["src/migration/*.ts"],
subscribers: [],

})

and still getting this error, remove the nodemon.json file if you have it in your project

Upvotes: 1

subharb
subharb

Reputation: 3472

In my case the entity in question was the only one giving the error. The rest of entities worked fine.

The automatic import failed to write correctly the name of the file.

import { BillingInfo } from "../entity/Billinginfo";

instead of

import { BillingInfo } from "../entity/BillingInfo";

The I for Info should be capital. The IDE also failed to show any errors on this import.

Upvotes: 1

Nsikak Essien
Nsikak Essien

Reputation: 1

I omitted this @Entity() decorator on the entity class. So immediately I fixed this, and it worked for me. Example:

import { ObjectType, Field, ID } from '@nestjs/graphql';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@ObjectType()
@Entity()
export class Message {
  @Field((type) => ID)
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Field()
  @Column()
  conversationId: string;

  @Field()
  @Column()
  sender: string;
}

Upvotes: 0

wuahi
wuahi

Reputation: 59

Just in case someone runs into the same problem i had. I had to do two different things going against me:

I was missing the declaration of entity in ormConfig:

ormConfig={
  ...,
  entities: [
     ...,
     UserEntity
  ]

}

And since i was making changes (afterwards) to an existing entity, the cache was throwing a similar error. The solution for this was to remove the projects root folders: dist/ folder. Thou this might only be a Nest.js + TypeOrm issue.

Upvotes: 1

PR7
PR7

Reputation: 1914

Make sure you have established a connection with the database before using the entities. In my case, I was using the AppDataSource before it was initialized. Here is how I fixed it:

import "reflect-metadata";
import { DataSource } from "typeorm";
import { Season } from "src/models/Season";

const AppDataSource = new DataSource({
  type: "postgres",
  host: "localhost",
  port: 5432,
  username: "postgres",
  password: "postgres",
  database: "test-db",
  synchronize: false,
  logging: false,
  entities: [Season],
  migrations: [],
  subscribers: [],
});

AppDataSource.initialize()
  .then(async () => {
    console.log("Connection initialized with database...");
  })
  .catch((error) => console.log(error));

export const getDataSource = (delay = 3000): Promise<DataSource> => {
  if (AppDataSource.isInitialized) return Promise.resolve(AppDataSource);

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (AppDataSource.isInitialized) resolve(AppDataSource);
      else reject("Failed to create connection with database");
    }, delay);
  });
};

And in your services where you want to use the DataSource:

import { getDataSource } from "src/config/data-source";
import { Season } from "src/models/Season";

const init = async (event) => {
  const AppDataSource = await getDataSource();
  const seasonRepo = AppDataSource.getRepository(Season);
  // Your business logic
};

You can also extend my function to add retry logic if required :)

Upvotes: 7

Malindu Upendra
Malindu Upendra

Reputation: 119

enable autoLoadEntities in app.module.ts

imports: [UserModule,
  TypeOrmModule.forRoot({
    autoLoadEntities: true
  })
]

Upvotes: 11

Suky
Suky

Reputation: 19

I've tried all the solutions above, changing the typeORM version solved it for me.

Upvotes: 1

Immanuel
Immanuel

Reputation: 1

Add your entity in orm.config.ts file.

entities: [empData,user],

Upvotes: 0

Barry
Barry

Reputation: 418

If your app is using the latest DataSource instead of OrmConfig (like apps using the latest version of typeorm (0.3.1 the moment i'm writing theses lines)), make sure to call initialize() method of your DataSource object inside your data-source.ts file before using it anywhere in your app.

Upvotes: 25

Related Questions