角色#用户的实体元数据未找到。

75
尝试使用TypeORM创建OneToManyManyToOne关系,但是我得到了以下错误。 我不知道我的代码哪里出错了。 我有以下用户实体:

尝试使用 TypeORM 创建OneToManyManyToOne关系,但是我得到了这个错误,我不知道我的代码哪里出了问题。

我有以下用户实体:

import { BaseEntity, Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Field, ID, ObjectType } from 'type-graphql';

import { Role } from './';

@ObjectType()
@Entity()
export class User extends BaseEntity {
  @Field(() => ID)
  @PrimaryGeneratedColumn()
  public id: number;

  @Field()
  @Column('text', { unique: true })
  public userName: string;

  @Column()
  public password: string;

  @Field()
  @Column('boolean', { default: true })
  public isActive: boolean;

  @ManyToOne(() => Role, role => role.users)
  @Field(() => Role, { nullable: true })
  public role: Role;
}

角色实体:

import { BaseEntity, Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Field, ID, ObjectType } from 'type-graphql';

import { User } from '.';

@ObjectType()
@Entity()
export class Role extends BaseEntity {
  @Field(() => ID)
  @PrimaryGeneratedColumn()
  public id: number;

  @Field()
  @Column('text', { unique: true })
  public name: string;

  @OneToMany(() => User, user => user.role, { lazy: false })
  @Field(() => [User], { nullable: true })
  public users: User[];
}

然而我一直遇到这个错误

(node:4541) UnhandledPromiseRejectionWarning: Error: Entity metadata
for Role#users was not found. Check if you specified a correct entity
object and if it's connected in the connection options. [1]     at
/node_modules/typeorm/metadata-builder/EntityMetadataBuilder.js:571:23
[1]     at Array.forEach (<anonymous>) [1]     at
EntityMetadataBuilder.computeInverseProperties
(/node_modules/typeorm/metadata-builder/EntityMetadataBuilder.js:567:34)
[1]     at
/node_modules/typeorm/metadata-builder/EntityMetadataBuilder.js:80:74
[1]     at Array.forEach (<anonymous>) [1]     at
EntityMetadataBuilder.build
(/node_modules/typeorm/metadata-builder/EntityMetadataBuilder.js:80:25)
[1]     at ConnectionMetadataBuilder.buildEntityMetadatas
(/node_modules/typeorm/connection/ConnectionMetadataBuilder.js:57:141)
[1]     at Connection.buildMetadatas
(/node_modules/typeorm/connection/Connection.js:494:57)
[1]     at Connection.<anonymous>
(/node_modules/typeorm/connection/Connection.js:126:30)
[1]     at step
(/node_modules/tslib/tslib.js:136:27) [1]
(node:4541) UnhandledPromiseRejectionWarning: Unhandled promise
rejection. This error originated either by throwing inside of an async
function without a catch block, or by rejecting a promise which was
not handled with .catch(). (rejection id: 1) [1] (node:4541) [DEP0018]
DeprecationWarning: Unhandled promise rejections are deprecated. In
the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.

6
如果你忘记在某个实体上添加@Entity注释,就会出现"未找到实体元数据"的错误。这些实体还必须在连接设置的"entities"部分进行声明(参见@Martin Konicek的答案)。 - Benny Code
对我来说,我添加了实体关系,导入相关的实体解决了这个问题。 - undefined
29个回答

137

我正在使用 NestJS 和 PostgreSQL,我遇到了相同的问题。问题是我忘记在模块中使用 TypeOrmModule.forFeature 函数导入实体。

@Module({
  imports: [TypeOrmModule.forFeature([Users, ...])],  <--- Importing the entity!
  controllers: [...],
  providers: [...],
  exports: [...],
})

22
先生,您应该获得一枚奖章。 - DerStoffel
只是补充一下:我在运行测试时也犯了同样的错误,因为即使在测试中,如果你正在使用数据库进行测试,你也需要注意这些实体。 - Luiz Fernando da Silva

52

如果您在应用其他解决方案后仍然存在问题,请检查实体是否有@Entity()装饰器。我之前缺少了这个,添加之后问题得到了解决。

还需要在连接选项中添加autoLoadEntities: true


1
你救了我的命! - WangJi

47

这意味着您的实体未被加载或加载不正确。

您需要修复实体的加载。实体通常将从ormconfig.js文件中加载。

只需创建一个名为ormconfig.js的文件,并输入类似于以下内容的内容,重点是实体

module.exports = {
  "name": "default",
  "type": "mongodb",
  "host": "localhost",
  "port": "27017",
  "username": "root",
  "password": "",
  "database": "rocketlaunches",
  "entities": [
    __dirname + "entities/**/*.entity.ts"
  ]
}

显然,您需要从项目中的任何位置加载实体。


4
好的,提醒我检查那个*.entity.ts文件的名称,谢谢。 - Chunlei Wang
1
没有想到需要完整路径。看到__dirname让我保持了很多理智。 - Zachary Dow
它对我有效。我将所有实体命名为 __dirname + "/entities/*.ts" 并且它可以工作。之前,我因为这个 __dirname + "entities/*.ts" 或者 __dirname + "./entities/*.ts" 而出现错误。 - Baris Senyerli
1
这也提醒我检查我的文件名。 我的 .entity.ts 有一个错别字。 - Forrest Wilkins

17

我遇到了同样的问题。

TypeORM 使用参数和元数据类/集合分散在各处,导致调试非常困难。经过多个小时的努力,我最终解决了这个问题。

所以这个关联关系失败是因为 EntityMetadataBuilder.ts 在尝试使用 === 将 ManyToOne 列的类型与已知实体类型进行关联。

var inverseEntityMetadata = entityMetadatas.find(function (m) {
  return m.target === relation.type || 
    (typeof relation.type === "string" && m.targetName === relation.type); 
});

通过查看relation.type,我发现它与m.target的"type"相同,但它们并没有指向相同的定义类型引用。对我来说,似乎我的相关类被node加载了多次。在阅读有关node如何缓存模块的信息后,我成功解决了问题,确保所有的import语句都引用了相同的文件,包括字符串中的大小写字母。
在一个文件中,我有以下内容:
import { Transaction } from "./transaction";

另一个我有的。
import { Transaction } from "./Transaction";

注意大写的“t”。将其替换为小写的“T”后,一切都按预期工作。

2
调试并不一定很难。如果你只是添加一个 console.log(relation.type); console.log(entityMetadatas);,你会发现它在一个值数组中寻找 [Function: Table],而这个数组应该包含 target: [Function: Table](在关系被指定为函数的情况下)。如果 entityMetadatas 没有一个带有该目标的值,那么该实体就会缺失于 createConnection 中。 - Pakman
我在 GitHub 上看到了这条评论。即使它们不同。 - Baris Senyerli
1
不得不暂时将文件名更改为 transactionz.ts,然后再改回 transaction.ts,以使文件系统与小写字母保持同步。 - Sir.Nathan Stassen

12

在我的项目中,TypeORM 是这样初始化的:

import { createConnection } from 'typeorm';

const conn = await createConnection({
  // Make sure to specify all entities here
  entities: [User, Role],

  // ... More options
})

只需要确保entities列出了你所有的实体。

(如果您没有使用ormconfig.js指定实体,则使用此方法。)


7

对于我的情况,我在类顶部缺少了@Entity(), 请检查您的所有类是否都有@Entity()修饰符。


6

我遇到了这个问题,在我的情况下,解决方法是删除服务器内的dist文件夹。


是的,它确实起作用了,因为您添加了新实体导致了问题。 - Frank Guo
1
+1 对我来说非常相关。我最初将文件命名为Upload.ts,然后改名为upload.ts。在dist文件夹中,它重命名为Upload.jsUpload.map。我不得不将文件重命名为uploadz.ts,更新所有导入,并清除dist文件夹。然后我才能重新命名为upload.ts - Sir.Nathan Stassen
这对我解决了问题。我重新命名了一些实体并相应地修改了迁移文件,但是dist文件夹需要被删除。 - undefined

5

在我的情况下,我通过将角色实体添加到主应用程序模块类中的实体数组中来解决了此问题。最初我忘记添加它。

TypeOrmModule.forRoot({
  type: process.env.DB_TYPE as any,
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT),
  username: process.env.DB_USERNAME,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  entities: [User, Role],
  synchronize: true,

3

在我的情况下,我忘记了在文件名中添加 .entity 部分。文件名应该是:user.entity.ts,而不是 user.ts,因为在我的配置文件中,我寻找以 .entity.ts 结尾的文件作为我的实体。

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

3

我的问题是我使用node-ts只运行我的项目中的typescript文件。然而,我的构建仍然发出被忽略/隐藏的.js文件。我不知道为什么,但清理*.js和*.js.map编译文件起作用了。奇怪的是我的ormconfig仅指定.ts文件。

我建议将"noEmit": true添加到tsconfig.json编译器选项中,以避免类似方法造成的任何未来头疼。


在删除了/dist文件夹后,它对我起作用了,这是TypeScript转译后JS文件的目标路径。 - Cappa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接