oguimbal / pg-mem

An in memory postgres DB instance for your unit tests

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using TypeORM JoinTable pointing to an entity table will cause duplicated table registration

leogcba opened this issue · comments

Describe the bug

This is hard to describe. Basically, when you use @JoinTable pointing to the same table used by the @Entity decorator, pg-mem treats each table as a different entity and tries to register the table twice. As the entity defines an enum type, the enum types is registered twice trowing the error.

The issue is in the _registerType(type){} function.

Failed SQL statement: CREATE TYPE "public"."device_activity_type" AS ENUM('Login', 'Logout');

To Reproduce

Create these entities:

export enum DeviceActivityType {
	Login = 'Login',
	Logout = 'Logout',
}

@Entity('device_activity') // THIS IS THE JOIN TABLE USED IN THE ENTITY BELOW
export class DeviceActivity extends BaseEntity {
	@PrimaryColumn({ type: 'uuid' })
	public deviceId: string;

	@PrimaryColumn({ type: 'uuid' })
	public customerId: string;

	@PrimaryColumn({ type: 'uuid' })
	public packageId: string;

	@PrimaryColumn({
		enum: DeviceActivityType,
		enumName: 'device_activity_type',
		type: 'enum',
	})
	public activityType: DeviceActivityType; // THIS MUST BE AN ENUM TO REPRODUCE THE ISSUE

	@Column({ type: 'text' })
	public name: string;

	@Column({ nullable: true, type: 'text' })
	public description?: string;
}
@Entity('devices')
export class Device extends BaseEntity {
	@PrimaryColumn({ type: 'uuid' })
	public id: string;

	@PrimaryColumn({ type: 'uuid' })
	public customerId: string;

	@Column()
	public hostname: string;

	@ManyToMany(() => Package)
	@JoinTable({
		inverseJoinColumns: [{ name: 'packageId' }, { name: 'customerId' }],
		joinColumns: [
			{ name: 'deviceId', referencedColumnName: 'id' },
			{ name: 'customerId', referencedColumnName: 'customerId' },
		],
		name: 'device_activity', // THIS MUST POINT TO THE TABLE ABOVE
	})
	public packages?: Package[];
}
@Entity('packages')
export class Package extends BaseEntity {
	@PrimaryColumn({ type: 'uuid' })
	public id: string;

	@Column()
	public name: string;

	@Column()
	public enabled: boolean;

	@Column({ type: 'uuid' })
	public customerId: string;

	@ManyToMany(() => Device)
	public devices: Device[];
}

Register the DB:

this.db.adapters.createTypeormDataSource({
	entities: [
		'src/**/device.entity.ts',
		'src/**/package.entity.ts',
		'src/**/deviceActivity.entity.ts',
	],
	synchronize: true,
	type: 'postgres',
})

pg-mem version

2.6.12