Describe the bug
mapToPk option returns nothing when its set on M:1 side and its populated from 1:M side
To Reproduce
import { Collection, Entity, ManyToOne, MikroORM, OneToMany, PrimaryKey } from '@mikro-orm/core';
import { AbstractSqlDriver } from '@mikro-orm/knex';
interface IA {
id: number;
entities: Collection<B>;
}
@Entity()
export class B {
@PrimaryKey()
id!: number;
@ManyToOne({ entity: 'A', mapToPk: true }) // Setting mapToPk to false does yield 2 results
entity!: IA;
}
@Entity()
export class A {
@PrimaryKey()
id!: number;
@OneToMany({ entity: 'B', mappedBy: 'entity' })
entities = new Collection<B>(this);
}
describe('GH issue 1128', () => {
let orm: MikroORM<AbstractSqlDriver>;
beforeAll(async () => {
orm = await MikroORM.init({
entities: [A, B],
dbName: ':memory:',
type: 'sqlite',
});
await orm.getSchemaGenerator().createSchema();
});
afterAll(() => orm.close(true));
test('mapToPk option returns nothing when its set on M:1 side and its populated from 1:M side', async () => {
const a = orm.em.create(A, {});
const b1 = orm.em.create(B, {
entity: a,
});
const b2 = orm.em.create(B, {
entity: a,
});
a.entities.add(b1, b2);
await orm.em.persistAndFlush(a);
orm.em.clear();
const entity = await orm.em.findOneOrFail(A, { id: 1 }, { populate: true });
expect(entity.entities).toHaveLength(2);
});
});
Expected behavior
I expected the mapToPk option to work when populating the relation from 1:M side.
Versions
| Dependency | Version |
| - | - |
| node | 12.18.4 |
| typescript | 4.0.3 |
| mikro-orm | 4.3.2 |
| mikro-orm/mysql | 4.3.2 |
This is wrong:
@ManyToOne({ entity: 'A', mapToPk: true })
entity!: IA; // using mapToPk means the type will be `number`, not `IA`
(but that is not connected to the issue itself)
Fixed in 4.3.3-dev.3
@B4nan I have installed the package for my project and it doesn't work properly. The relation doesn't get mapped to pk seems like mapToPk false and true do the same thing now. So my test is a false positive in that regard. Tested between version 4.3.2 where it was broken nothing was returned and version 4.3.3-dev.3 does return the relation but its not mapped to its pk.
Hmm your test is also wrong in that it creates the entity with a reference while using mapToPk.
const a = orm.em.create(A, {});
const b1 = orm.em.create(B, { entity: a }); // this is wrong, the `B.entity` is not instance of `A`
const b2 = orm.em.create(B, { entity: a }); // this is wrong, the `B.entity` is not instance of `A`
If you really want to use mapToPk and want to have B.entity as not nullable, you need to first flush the A entity to have its PK.
const a = orm.em.create(A, {});
await em.persistAndFlush(a);
const b1 = orm.em.create(B, { entity: a.id });
const b2 = orm.em.create(B, { entity: a.id });
a.entities.add(b1, b2);
await em.flush(); `a` is already managed, no need to persist again
(but again, that itself is not enough, there is indeed a bug in the propagation)
Check the updated test case, you might want to use explicit transaction to run it all in the same one (otherwise two flushes will result in two transactions).
Once built, it will be available as dev.5
Most helpful comment
Check the updated test case, you might want to use explicit transaction to run it all in the same one (otherwise two flushes will result in two transactions).
Once built, it will be available as
dev.5