Reputation: 230296
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
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):
[__dirname + '/../**/*.entity.{js,ts}']
.*.ts
or *.js
;3.1) Declare entity at forFeature
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);connect
method after initilize
@Entity()
decorator is present on all entity classes.autoLoadEntities
to TrueAppDataSource.initialize()
is awaited if necessary.dist/
Folder and Rebuilddist/
folder, especially if using NestJS, to avoid outdated compiled files.Billinginfo
vs. BillingInfo
.ormconfig.json
and ormconfig.ts
, to avoid confusion.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;TypeOrmModuleAsyncOptions
.Hope to help someone (or myself in the next time). Cheers
Upvotes: 2
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
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
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
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
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
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
Reputation: 583
The problem is on ormConfig
Please try to use this:
entities: [__dirname + '/../**/*.entity.{js,ts}']
Upvotes: 48
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
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
Reputation: 132
if you get "Error: No metadata for Quiz was found" because different version. Here is my solution:
I dont need quiz.repository.ts file ---- from a youtube comment and the solution worked for me.
Upvotes: 0
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
Reputation: 121
Try this one. Should never fall
DB_ENTITIES=[dist/**/*.entity.js]
Upvotes: 0
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
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
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
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
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
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
Reputation: 732
For me it was two things, while using it with NestJS:
Once I fixed it, the error still happened, then I got to point two:
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
and then i check the entities
path . i modify the path to correct. then the typeorm working
Upvotes: 2
Reputation: 232
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
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
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
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
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
Reputation: 119
enable autoLoadEntities in app.module.ts
imports: [UserModule,
TypeOrmModule.forRoot({
autoLoadEntities: true
})
]
Upvotes: 11
Reputation: 19
I've tried all the solutions above, changing the typeORM version solved it for me.
Upvotes: 1
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