So the back story is I'm working in a company and continued their code. I'm able to recreate the problem in a fresh nestjs project, so I have 4 entity (for demonstration purposes only)
// User Entity
import { Column, Entity, PrimaryGeneratedColumn, TableInheritance } from "typeorm";
import { PolymorphicChildren } from "typeorm-polymorphic";
import { AdvertEntity } from "./advert.entity";
@Entity('m_users')
@TableInheritance({ column: { type: "varchar", name: "type" } })
export class UserEntity{
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@Column()
email: string;
@Column()
password: string;
@PolymorphicChildren(()=>AdvertEntity,{
eager:false
})
adverts: AdvertEntity[];
}
// Employee Entity
import { ChildEntity, Column, JoinTable, ManyToMany } from "typeorm";
import { MerchantEntity } from "./merchant.entity";
import { UserEntity } from "./user.entity";
@ChildEntity()
export class EmployeeEntity extends UserEntity{
@Column()
room: string;
@ManyToMany(()=>MerchantEntity)
@JoinTable()
merchants: MerchantEntity[];
}
// Merchant Entity
import { Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm";
import { PolymorphicChildren } from "typeorm-polymorphic";
import { AdvertEntity } from "./advert.entity";
import { EmployeeEntity } from "./employee.entity";
@Entity('m_merchants')
export class MerchantEntity{
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
name: string;
@PolymorphicChildren(()=>AdvertEntity,{
eager: false
})
adverts: AdvertEntity[];
@ManyToMany(()=>EmployeeEntity)
@JoinTable()
employees: EmployeeEntity[];
}
// Adverts Entity
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import { PolymorphicParent } from "typeorm-polymorphic";
import { PolymorphicChildInterface } from "typeorm-polymorphic/dist/polymorphic.interface";
import { MerchantEntity } from "./merchant.entity";
import { UserEntity } from "./user.entity";
@Entity('m_adverts')
export class AdvertEntity implements PolymorphicChildInterface{
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
target: string;
@PolymorphicParent(()=> [ UserEntity, MerchantEntity])
owner: UserEntity | MerchantEntity;
@Column()
entityId: string;
@Column()
entityType: string;
}
When I ran these code I got this errors
export class EmployeeEntity extends UserEntity{
^
TypeError: Class extends value undefined is not a constructor or null
at Object.<anonymous> (/Users/digitalenvision/sandbox/nest-sb-1/src/entity/employee.entity.ts:6:37)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/Users/digitalenvision/sandbox/nest-sb-1/src/entity/merchant.entity.ts:4:1)
at Module._compile (node:internal/modules/cjs/loader:1103:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
digitalenvision@Digitals-MacBook-Pro-3 nest-sb-1 % npm run start
So the thing is that Merchant, Employee and Adverts has circular references between them. These issues went gone when I tried remove Merchant from the Polymorphic relation on AdvertsEntity, or I remove the many-to-many relation between Employee and Merchant. But we still need both many-to-many relation and the polymorphic relation. I tried a few solution from a few forum but still no luck for me. Any suggestion regarding these problem? Thanks
So I don't think it is possible to have polymorphic relation to a parent, my superior also think so. The solution was to have polymorphic relation with the child. Changing
// User entity
...
// remove these relation
// @PolymorphicChildren(()=>AdvertEntity,{
// eager:false
// })
// adverts: AdvertEntity[];
...
// Employee Entity
...
// add the relation
@PolymorphicChildren(()=>AdvertEntity,{
eager: false
})
adverts: AdvertEntity[];
...
// AdvertEntity
...
// change to
@PolymorphicParent(()=> [ EmployeeEntity, MerchantEntity])
owner: EmployeeEntity | MerchantEntity;
...
solved my issue. thanks