When two STI subclasses both declare a @OneToMany with the same property name but different target entities, MikroORM.init crashes:
TypeError: rootProp.fieldNames is not iterable
at MetadataDiscovery.js:1339:49
at MetadataDiscovery.initSingleTableInheritance (MetadataDiscovery.js:1311)
Looks like the inverse-side counterpart of #7598. The fix in #7599 added sameRelationTargetRoot() to skip the rename branch for narrowed owning-side overrides, but it bails out for anything that isn't MANY_TO_ONE or ONE_TO_ONE:
if (prop.kind !== ReferenceKind.MANY_TO_ONE && prop.kind !== ReferenceKind.ONE_TO_ONE) {
return false;
}
So OneToMany falls through into the rename branch, hits initFieldName(rootProp, ...) which doesn't set fieldNames for inverse-side props, and then [...rootProp.fieldNames] blows up.
The targets in the repro aren't narrowing the same hierarchy either — they're entirely separate entities — so the rename branch shouldn't run for them at all.
Expected behavior
Discovery should succeed. OneToMany on STI siblings has no column to merge, so it should just inherit.
Reproduction
npm i @mikro-orm/core@7.0.13 @mikro-orm/postgresql@7.0.13 and run:
import { MikroORM, defineEntity } from '@mikro-orm/core';
const p = defineEntity.properties;
const Animal = defineEntity({
name: 'Animal',
abstract: true,
discriminatorColumn: 'type',
properties: {
id: p.string().primary(),
type: p.string(),
name: p.string(),
},
});
const DogToy = defineEntity({
name: 'DogToy',
properties: {
id: p.string().primary(),
name: p.string(),
owner: () => p.manyToOne(Dog),
},
});
const CatToy = defineEntity({
name: 'CatToy',
properties: {
id: p.string().primary(),
name: p.string(),
owner: () => p.manyToOne(Cat),
},
});
const Dog = defineEntity({
name: 'Dog',
extends: Animal,
discriminatorValue: 'DOG',
properties: {
toys: () => p.oneToMany(DogToy).mappedBy('owner'),
},
});
const Cat = defineEntity({
name: 'Cat',
extends: Animal,
discriminatorValue: 'CAT',
properties: {
toys: () => p.oneToMany(CatToy).mappedBy('owner'),
},
});
const { PostgreSqlDriver } = await import('@mikro-orm/postgresql');
await MikroORM.init({
driver: PostgreSqlDriver,
entities: [Animal, Dog, Cat, DogToy, CatToy],
dbName: 'never_connects',
connect: false,
});
What driver are you using?
@mikro-orm/postgresql
MikroORM version
7.0.13
Node.js version
24.15.0
Operating system
Windows 11
Validations
When two STI subclasses both declare a
@OneToManywith the same property name but different target entities,MikroORM.initcrashes:Looks like the inverse-side counterpart of #7598. The fix in #7599 added
sameRelationTargetRoot()to skip the rename branch for narrowed owning-side overrides, but it bails out for anything that isn'tMANY_TO_ONEorONE_TO_ONE:So OneToMany falls through into the rename branch, hits
initFieldName(rootProp, ...)which doesn't setfieldNamesfor inverse-side props, and then[...rootProp.fieldNames]blows up.The targets in the repro aren't narrowing the same hierarchy either — they're entirely separate entities — so the rename branch shouldn't run for them at all.
Expected behavior
Discovery should succeed. OneToMany on STI siblings has no column to merge, so it should just inherit.
Reproduction
npm i @mikro-orm/core@7.0.13 @mikro-orm/postgresql@7.0.13and run:What driver are you using?
@mikro-orm/postgresql
MikroORM version
7.0.13
Node.js version
24.15.0
Operating system
Windows 11
Validations