Я уже некоторое время использую TypeORM без проблем, но затем внезапно появляется эта ошибка при вызове API:
EntityMetadataNotFound: No metadata for "BusinessApplication" was found.
at new EntityMetadataNotFoundError (C:\Users\Robbie\Code\fit-society\node_modules\typeorm\error\EntityMetadataNotFoundError.js:10:28)
at Connection.getMetadata (C:\Users\Robbie\Code\fit-society\node_modules\typeorm\connection\Connection.js:336:19)
at EntityManager.<anonymous> (C:\Users\Robbie\Code\fit-society\node_modules\typeorm\entity-manager\EntityManager.js:459:44)
at step (C:\Users\Robbie\Code\fit-society\node_modules\tslib\tslib.js:136:27)
at Object.next (C:\Users\Robbie\Code\fit-society\node_modules\tslib\tslib.js:117:57)
at C:\Users\Robbie\Code\fit-society\node_modules\tslib\tslib.js:110:75
at new Promise (<anonymous>)
at Object.__awaiter (C:\Users\Robbie\Code\fit-society\node_modules\tslib\tslib.js:106:16)
at EntityManager.find (C:\Users\Robbie\Code\fit-society\node_modules\typeorm\entity-manager\EntityManager.js:456:24)
at module.exports../src/pages/api/business-applications/[id].ts.__webpack_exports__.default.Object (C:\Users\Robbie\Code\fit-society\.next\server\static\development\pages\api\business-applications\[id].js:1648:65)
at process._tickCallback (internal/process/next_tick.js:68:7)
Это происходит, когда вызывается этот код:
import { BusinessApplication } from '../../../backend/all-entities';
import db from '../../../backend/database';
// in a function...
const manager = await db.getManager();
// in this case, req.data.id does equal "oldest"
const application: BusinessApplication | undefined =
req.data.id === 'oldest'
? (await manager.find(BusinessApplication, { order: { dateSubmitted: 'DESC' }, take: 1 }))[0]
: await manager.findOne(BusinessApplication, { where: { id: parseInt(req.data.id, 10) } });
if (application == null) throw createError(404, 'Business application not found');
return application;
В backend / all-entity.ts:
/**
* This file exists to solve circular dependency problems with Webpack by explicitly specifying the module loading order.
* @see https://medium.com/visual-development/how-to-fix-nasty-circular-dependency-issues-once-and-for-all-in-javascript-typescript-a04c987cf0de
*/
import Account_ from './entities/Account';
export { default as Qualification } from './entities/Qualification';
export { default as EditableAccount } from './entities/EditableAccount';
export { default as EditableBusiness } from './entities/EditableBusiness';
export { default as Business } from './entities/Business';
export { default as BusinessApplication, SendableBusinessApplication } from './entities/BusinessApplication';
export { default as EditableCustomer } from './entities/EditableCustomer';
export { default as Customer } from './entities/Customer';
export { default as Offer } from './entities/Offer';
export { default as ProductOffer } from './entities/ProductOffer';
export { default as ServiceOffer } from './entities/ServiceOffer';
В backend / database.ts:
import 'reflect-metadata';
import {
Connection,
ConnectionManager,
ConnectionOptions,
createConnection,
EntityManager,
getConnectionManager
} from 'typeorm';
import { Business, BusinessApplication, Customer, ProductOffer, ServiceOffer, Qualification } from './all-entities';
/**
* Database manager class
*/
class Database {
private connectionManager: ConnectionManager;
constructor() {
this.connectionManager = getConnectionManager();
}
private async getConnection(): Promise<Connection> {
const CONNECTION_NAME = 'default';
let connection: Connection;
if (this.connectionManager.has(CONNECTION_NAME)) {
connection = this.connectionManager.get(CONNECTION_NAME);
if (!connection.isConnected) {
connection = await connection.connect();
}
} else {
const connectionOptions: ConnectionOptions = {
name: CONNECTION_NAME,
type: 'postgres',
url: process.env.DATABASE_URL,
synchronize: true,
entities: [Business, BusinessApplication, Qualification, Customer, ProductOffer, ServiceOffer]
};
connection = await createConnection(connectionOptions);
}
return connection;
}
public getManager(): Promise<EntityManager> {
return this.getConnection().then(conn => conn.manager);
}
}
const db = new Database();
export default db;
В backend / entity / BusinessApplication.ts:
import { IsIn, IsString, IsOptional } from 'class-validator';
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { EditableBusiness } from '../all-entities';
class PasswordlessBusinessApplication extends EditableBusiness {
@Column()
@IsIn(['individual', 'company'])
type!: 'individual' | 'company';
@Column({ nullable: true })
@IsOptional()
@IsString()
fein?: string;
@Column({ nullable: true })
@IsOptional()
@IsString()
professionalCertificationUrl?: string;
}
@Entity()
export default class BusinessApplication extends PasswordlessBusinessApplication {
@PrimaryGeneratedColumn()
id!: number;
@CreateDateColumn()
dateSubmitted!: Date;
@Column()
@IsString()
passwordHash!: string;
}
/**
* A business application sent by the client, which contains a password instead of a password hash.
* Qualification objects do not require id or business.
*/
export class SendableBusinessApplication extends PasswordlessBusinessApplication {
@IsString()
password!: string;
}
Из того, что я вижу, все импортируемые точки указывают на нужный файл, я импортировал метаданные отражений и поместил декоратор @Entity()
в класс BusinessApplication
. Так что может пойти не так? Примечательно, что если я изменю await manager.find(BusinessApplication, ...)
в первом файле на await manager.find('BusinessApplication', ...)
, он будет работать нормально, но я не хочу этого делать, потому что потеряю intellisense. Кроме того, эта ошибка не возникает при первой инициализации сервера, но после его горячей перезагрузки модулем Webpack происходит сбой (это может произойти после того, как Next. js удалит страницу или после того, как я изменю код) .