试图保留未发现的对象类型实体
Trying to persist not discovered entity of type object
问题
我是 Nest.js
和 Mikro-ORM
的新手,我必须将其作为工作要求来学习。
这个栈需要TypeScript
,我打心底里很鄙视,但是又不得不做
我已经设置了我的应用程序,当我执行 npm run start:dev
时,它启动时没有问题。
但是,当我尝试向数据库添加内容时,它突然出现并出现以下错误块:
[Nest] 5368 - 07/03/2021, 11:52:15 PM [ExceptionsHandler] Trying to persist not discovered entity of type object. +183188ms
ValidationError: Trying to persist not discovered entity of type object.
at Function.notDiscoveredEntity (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/errors.js:51:16)
at SqlEntityManager.persist (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/EntityManager.js:438:48)
at SqlEntityManager.persistAndFlush (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/EntityManager.js:449:20)
at SqlEntityRepository.persistAndFlush (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/entity/EntityRepository.js:21:23)
at UsersService.create (/home/lazar/tuts/backend/dist/users/users.service.js:47:35)
at UsersController.create (/home/lazar/tuts/backend/dist/users/users.controller.js:25:40)
at /home/lazar/tuts/backend/node_modules/@nestjs/core/router/router-execution-context.js:38:29
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async /home/lazar/tuts/backend/node_modules/@nestjs/core/router/router-execution-context.js:46:28
at async /home/lazar/tuts/backend/node_modules/@nestjs/core/router/router-proxy.js:9:17
这是我第一次走进这个堆栈,我不知道这个错误是什么意思。当我 Google 这个错误时,我没有得到任何有用的东西。我该怎么做才能让它消失?
相关代码
- 实体(
User.ts
)
import { Entity, PrimaryKey, Property } from "@mikro-orm/core";
@Entity()
export class User {
@PrimaryKey()
id!: string;
@Property()
email!: string;
@Property()
name!: string;
@Property()
password!: string;
@Property({ type: 'date' })
createdAt = new Date()
@Property({ type: 'date', onUpdate: () => new Date() })
updatedAt = new Date()
};
- 控制器(
users.controller.ts
)
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { CreateUserDTO } from './dto/create-user.dto';
import { User } from './interfaces/user.interface';
import { UsersService } from './users.service';
import { User as UserEntity } from "../entities/User"
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Post()
async create(@Body() createUserDto: CreateUserDTO): Promise<User> {
console.log("CREATEUSERDTO", createUserDto);
return await this.usersService.create(createUserDto)
}
}
- 服务(
users.service.ts
)
import { EntityRepository } from '@mikro-orm/core';
import { Injectable } from '@nestjs/common';
import { User } from './interfaces/user.interface';
import { User as UserEntity } from "../entities/User"
import { InjectRepository } from '@mikro-orm/nestjs';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(UserEntity)
private readonly userRepository: EntityRepository<UserEntity>
) {}
async create(user: User): Promise<UserEntity> {
console.log("ALL GOOD");
const newUser = this.userRepository.create(user)
console.log("ALL GOOD");
console.log("NEW USER", newUser);
await this.userRepository.persistAndFlush(user)
console.log("ALL GOOD");
return newUser
}
}
- 模块(
users.module.ts
)
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { Module } from '@nestjs/common';
import { User } from 'src/entities/User';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
imports: [MikroOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService]
})
export class UsersModule {}
- DTO
export class CreateUserDTO {
readonly name: string;
readonly email: string;
readonly password: string;
readonly createdAt: Date;
readonly updatedAt: Date;
}
- 界面
export interface User {
id?: string;
name: string;
email: string;
password: string;
createdAt: Date;
updatedAt: Date;
}
正如评论中 Micael Levi 已经指出的那样,这是由于您试图持久化 POJO/DTO 而不是实体实例造成的。
const dto = { name: '...', email: '...' };
const user = em.create(User, dto);
// this is basically what you are doing and will fail as the prototype
// is just `Object` - which is what you see in the error
em.persist(dto);
// and this is what you need to do instead
em.persist(user);
您始终需要使用实体实例,以便 ORM 知道要使用哪些元数据。如果您只有 Object
,则无法将对象与正确的数据库相关联 table。
我遇到了同样的问题,我认为该错误与标识映射上下文有关,通过使用合并,它应该将其添加到实体管理器使用的上下文映射中。
em.merge(row)
“将给定的实体合并到此 EntityManager,使其成为托管的。您可以通过第二个参数强制刷新现有实体。默认情况下,它将 return 已经加载的实体而不修改它们。”
问题
我是 Nest.js
和 Mikro-ORM
的新手,我必须将其作为工作要求来学习。
这个栈需要TypeScript
,我打心底里很鄙视,但是又不得不做
我已经设置了我的应用程序,当我执行 npm run start:dev
时,它启动时没有问题。
但是,当我尝试向数据库添加内容时,它突然出现并出现以下错误块:
[Nest] 5368 - 07/03/2021, 11:52:15 PM [ExceptionsHandler] Trying to persist not discovered entity of type object. +183188ms
ValidationError: Trying to persist not discovered entity of type object.
at Function.notDiscoveredEntity (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/errors.js:51:16)
at SqlEntityManager.persist (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/EntityManager.js:438:48)
at SqlEntityManager.persistAndFlush (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/EntityManager.js:449:20)
at SqlEntityRepository.persistAndFlush (/home/lazar/tuts/backend/node_modules/@mikro-orm/core/entity/EntityRepository.js:21:23)
at UsersService.create (/home/lazar/tuts/backend/dist/users/users.service.js:47:35)
at UsersController.create (/home/lazar/tuts/backend/dist/users/users.controller.js:25:40)
at /home/lazar/tuts/backend/node_modules/@nestjs/core/router/router-execution-context.js:38:29
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async /home/lazar/tuts/backend/node_modules/@nestjs/core/router/router-execution-context.js:46:28
at async /home/lazar/tuts/backend/node_modules/@nestjs/core/router/router-proxy.js:9:17
这是我第一次走进这个堆栈,我不知道这个错误是什么意思。当我 Google 这个错误时,我没有得到任何有用的东西。我该怎么做才能让它消失?
相关代码
- 实体(
User.ts
)
import { Entity, PrimaryKey, Property } from "@mikro-orm/core";
@Entity()
export class User {
@PrimaryKey()
id!: string;
@Property()
email!: string;
@Property()
name!: string;
@Property()
password!: string;
@Property({ type: 'date' })
createdAt = new Date()
@Property({ type: 'date', onUpdate: () => new Date() })
updatedAt = new Date()
};
- 控制器(
users.controller.ts
)
import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common';
import { CreateUserDTO } from './dto/create-user.dto';
import { User } from './interfaces/user.interface';
import { UsersService } from './users.service';
import { User as UserEntity } from "../entities/User"
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Post()
async create(@Body() createUserDto: CreateUserDTO): Promise<User> {
console.log("CREATEUSERDTO", createUserDto);
return await this.usersService.create(createUserDto)
}
}
- 服务(
users.service.ts
)
import { EntityRepository } from '@mikro-orm/core';
import { Injectable } from '@nestjs/common';
import { User } from './interfaces/user.interface';
import { User as UserEntity } from "../entities/User"
import { InjectRepository } from '@mikro-orm/nestjs';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(UserEntity)
private readonly userRepository: EntityRepository<UserEntity>
) {}
async create(user: User): Promise<UserEntity> {
console.log("ALL GOOD");
const newUser = this.userRepository.create(user)
console.log("ALL GOOD");
console.log("NEW USER", newUser);
await this.userRepository.persistAndFlush(user)
console.log("ALL GOOD");
return newUser
}
}
- 模块(
users.module.ts
)
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { Module } from '@nestjs/common';
import { User } from 'src/entities/User';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
imports: [MikroOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService]
})
export class UsersModule {}
- DTO
export class CreateUserDTO {
readonly name: string;
readonly email: string;
readonly password: string;
readonly createdAt: Date;
readonly updatedAt: Date;
}
- 界面
export interface User {
id?: string;
name: string;
email: string;
password: string;
createdAt: Date;
updatedAt: Date;
}
正如评论中 Micael Levi 已经指出的那样,这是由于您试图持久化 POJO/DTO 而不是实体实例造成的。
const dto = { name: '...', email: '...' };
const user = em.create(User, dto);
// this is basically what you are doing and will fail as the prototype
// is just `Object` - which is what you see in the error
em.persist(dto);
// and this is what you need to do instead
em.persist(user);
您始终需要使用实体实例,以便 ORM 知道要使用哪些元数据。如果您只有 Object
,则无法将对象与正确的数据库相关联 table。
我遇到了同样的问题,我认为该错误与标识映射上下文有关,通过使用合并,它应该将其添加到实体管理器使用的上下文映射中。
em.merge(row)
“将给定的实体合并到此 EntityManager,使其成为托管的。您可以通过第二个参数强制刷新现有实体。默认情况下,它将 return 已经加载的实体而不修改它们。”