#TypeORM EntityMetadataNotFoundError when loading entity from directory in data-source.ts

19 messages · Page 1 of 1 (latest)

drifting jay
#

Hello, I'm running into a typeorm issue when loading entities from a directory. For example, entities: ['entity/*.ts'] instead of entities: [User]. More information below using a default typeorm project (typeorm init). The only change between the default project and my issue is the entities value in data-source.ts.

Error details:

PS C:\foo> npm start

> start
> ts-node src/index.ts

Inserting a new user into the database...
EntityMetadataNotFoundError: No metadata for "User" was found.
    at DataSource.getMetadata (C:\foo\src\data-source\DataSource.ts:438:30)
    at C:\foo\src\persistence\EntityPersistExecutor.ts:84:56
    at Array.forEach (<anonymous>)
    at C:\foo\src\persistence\EntityPersistExecutor.ts:77:30
    at Array.map (<anonymous>)
    at EntityPersistExecutor.execute (C:\foo\src\persistence\EntityPersistExecutor.ts:73:34)

Setting up new project:

PS C:\foo> npm install typeorm reflect-metadata @types/node better-sqlite3 --save
PS C:\foo> typeorm init --database better-sqlite3                                
Project created inside current directory.
Please wait, installing dependencies...
Done! Start playing with a new project!

Original data-source.ts:

export const AppDataSource = new DataSource({
    type: "better-sqlite3",
    database: "database.sqlite",
    synchronize: true,
    logging: false,
    entities: [User],
    migrations: [],
    subscribers: [],
})

Updated data-source.ts:

export const AppDataSource = new DataSource({
    type: "better-sqlite3",
    database: "database.sqlite",
    synchronize: true,
    logging: false,
    entities: ['entity/*.ts'],
    migrations: [],
    subscribers: [],
})
undone thistle
#

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

#

Don't forget js files too

#

When tsc builds, it'll need to look for js files

#

But be warn that conflict can exist there

#

If both dist and src are valid

drifting jay
#

It's still giving the same EntityMetadataNotFound error after updating to entities: ["build/entity/**/*.{ts,js}","src/entity/**/*.{ts,js}"],. Everything else is unchanged from the default typeorm init project. Any idea what's wrong? Thanks for the help.

Run output

PS C:\foo> npx tsc --project .\tsconfig.json

PS C:\foo> node .\build\index.js
Inserting a new user into the database...
EntityMetadataNotFoundError: No metadata for "User" was found.
[truncated - same output as before]

PS C:\foo> ts-node src\index.ts
Inserting a new user into the database...
EntityMetadataNotFoundError: No metadata for "User" was found.
[truncated - same output as before]

This is the directory structure

.
│   database.sqlite
│   package-lock.json
│   package.json
│   README.md
│   tsconfig.json
└───src
    │   data-source.ts
    │   index.ts
    ├───entity
    │       User.ts
    └───migration

tsconfig.json

{
   "compilerOptions": {
      "lib": [
         "es5",
         "es6"
      ],
      "target": "es5",
      "module": "commonjs",
      "moduleResolution": "node",
      "outDir": "./build",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "sourceMap": true
   }
}
undone thistle
#

Do you export User class ?

#

And try src/entity/*.ts and build/entity/*.js in

drifting jay
#

Yes, this is the default User.ts

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number

    @Column()
    firstName: string

    @Column()
    lastName: string

    @Column()
    age: number

}

I've also tried these different values:
entities: ["build/entity/*.js","src/entity/*.ts"],
entities: ["build/entity/User.js","src/entity/User.ts"],
entities: ["entity/User.js","entity/User.ts"],
It's the same error. Even explicit paths didn't help.

thin cape
#

make sure you import "reflect-metadata" as your first import in your entry point

drifting jay
#

It's imported in data-source.ts:

import "reflect-metadata"
import { DataSource } from "typeorm"
import { User } from "./entity/User"

export const AppDataSource = new DataSource({
    type: "better-sqlite3",
    database: "database.sqlite",
    synchronize: true,
    logging: false,
    entities: ["entity/User.js","entity/User.ts"],
    migrations: [],
    subscribers: [],
})

index.ts

import { AppDataSource } from "./data-source"
import { User } from "./entity/User"

AppDataSource.initialize().then(async () => {

    console.log("Inserting a new user into the database...")
    const user = new User()
    // [Truncated]

}).catch(error => console.log(error))

Should index.ts also import it too?

thin cape
#

no, import it in index.ts

#

since index.ts imports your AppDataSource

#

it need to be imported before AppDataSource is imported

#

[...] global place of your app

drifting jay
#

The default project created by typeorm init does the import in data-source.ts, maybe the project template or the documentation might be outdated. Adding import "reflect-metadata" to index.ts still gives the same error.

Here is the sample project.
It is unchanged from the default typeorm init project apart from 1 line in index.ts to import reflect-metadata and 1 line in data-source.ts to update entities location

drifting jay
#

After digging through the source, this was an issue with the glob dependency. nodejs does path normalization on windows in a way that is not compatible with glob by default. Just as I was writing up a fix on my end, I found a merged PR for the issue: https://github.com/typeorm/typeorm/pull/9768

GitHub

Fixes #9766
Description of change
Replace backslashes with forward slashes when normalizing a path on Windows, in order to make the path work for glob pattern resolving.

undone thistle
#

!resolved