diff --git a/packages/knex/src/query/QueryBuilder.ts b/packages/knex/src/query/QueryBuilder.ts index aa91fac320ca..d6c35f6a250b 100644 --- a/packages/knex/src/query/QueryBuilder.ts +++ b/packages/knex/src/query/QueryBuilder.ts @@ -22,6 +22,7 @@ import type { RequiredEntityData, } from '@mikro-orm/core'; import { + helper, LoadStrategy, LockMode, PopulateHint, @@ -632,7 +633,30 @@ export class QueryBuilder { res = this.driver.mergeJoinedResult(res, this.mainAlias.metadata!); } - return res.map(r => this.em!.map(this.mainAlias.entityName, r, { schema: this._schema })); + const entities: T[] = []; + + function propagatePopulateHint(entity: U, hint: PopulateOptions[]) { + helper(entity).__serializationContext.populate ??= hint; + hint.forEach(pop => { + const value = entity[pop.field]; + + if (Utils.isEntity(value, true)) { + helper(value).populated(); + propagatePopulateHint(value, pop.children ?? []); + } else if (Utils.isCollection(value)) { + value.populated(); + value.getItems(false).forEach(item => propagatePopulateHint(item, pop.children ?? [])); + } + }); + } + + for (const r of res) { + const entity = this.em!.map(this.mainAlias.entityName, r, { schema: this._schema }); + propagatePopulateHint(entity, this._populate); + entities.push(entity); + } + + return entities; } /** diff --git a/tests/issues/GH3812.test.ts b/tests/issues/GH3812.test.ts index 01ac55468c42..4d2e75b342ec 100644 --- a/tests/issues/GH3812.test.ts +++ b/tests/issues/GH3812.test.ts @@ -173,6 +173,7 @@ test('GH 3812', async () => { const res1 = await orm.em.find(SerialNumber, {}, { populate: ['logs.step'] }); expect(res1).toHaveLength(1); expect(wrap(res1[0]).toJSON().logs[0].serialNumber).toBe('559fccf7-11f0-4e5a-8e15-ae29b98ddeb3'); + expect(wrap(res1[0]).toJSON().logs[0].step?.name).toBe('ASSY'); orm.em.clear(); @@ -185,4 +186,5 @@ test('GH 3812', async () => { .getResultList(); expect(res2).toHaveLength(1); expect(wrap(res2[0]).toJSON().logs[0].serialNumber).toBe('559fccf7-11f0-4e5a-8e15-ae29b98ddeb3'); + expect(wrap(res2[0]).toJSON().logs[0].step?.name).toBe('ASSY'); });