@mikro-orm/core 7.2.1-dev.2 → 7.2.1-dev.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ import type { AnyString, ArrayElement, AutoPath, ConnectionType, Dictionary, Ent
11
11
  import type { Routine } from './metadata/Routine.js';
12
12
  import { FlushMode, LockMode, PopulatePath, type TransactionOptions } from './enums.js';
13
13
  import type { MetadataStorage } from './metadata/MetadataStorage.js';
14
- import type { AbortQueryOptions, InflightQueryAbortStrategy, Transaction } from './connections/Connection.js';
14
+ import type { AbortQueryOptions, Connection, InflightQueryAbortStrategy, Transaction } from './connections/Connection.js';
15
15
  import { EventManager } from './events/EventManager.js';
16
16
  import type { EntityComparator } from './utils/EntityComparator.js';
17
17
  /**
@@ -130,7 +130,7 @@ export declare class EntityManager<Driver extends IDatabaseDriver = IDatabaseDri
130
130
  *
131
131
  * @internal
132
132
  */
133
- withSessionContext<T>(ctx: Transaction | undefined, cb: (ctx?: Transaction) => Promise<T>): Promise<T>;
133
+ withSessionContext<T>(ctx: Transaction | undefined, cb: (ctx?: Transaction) => Promise<T>, connection?: Connection): Promise<T>;
134
134
  /**
135
135
  * Sets logger context for this entity manager.
136
136
  */
package/EntityManager.js CHANGED
@@ -399,13 +399,16 @@ export class EntityManager {
399
399
  *
400
400
  * @internal
401
401
  */
402
- async withSessionContext(ctx, cb) {
402
+ async withSessionContext(ctx, cb, connection) {
403
403
  const em = this.getContext(false);
404
404
  const sessionContext = ctx ? undefined : em.getTransactionSessionContext();
405
405
  if (!sessionContext) {
406
406
  return cb(ctx);
407
407
  }
408
- return em.getConnection('write').transactional(trx => cb(trx), { sessionContext, loggerContext: em.loggerContext });
408
+ return (connection ?? em.getConnection('write')).transactional(trx => cb(trx), {
409
+ sessionContext,
410
+ loggerContext: em.loggerContext,
411
+ });
409
412
  }
410
413
  /**
411
414
  * Sets logger context for this entity manager.
@@ -486,7 +489,8 @@ export class EntityManager {
486
489
  return userFilter;
487
490
  }
488
491
  const ret = {};
489
- for (const hint of options.populate) {
492
+ const populate = options.populate;
493
+ for (const hint of populate) {
490
494
  const field = hint.field.split(':')[0];
491
495
  const prop = meta.properties[field];
492
496
  const strategy = getLoadingStrategy(prop.strategy || hint.strategy || options.strategy || this.config.get('loadStrategy'), prop.kind);
@@ -530,6 +534,16 @@ export class EntityManager {
530
534
  if (userFilter) {
531
535
  Utils.merge(ret, userFilter);
532
536
  }
537
+ for (const hint of populate) {
538
+ const [field, ref] = hint.field.split(':');
539
+ // Filtered M:N refs need the target join and its PKs (unless a plain hint for the field already provides them).
540
+ if (ref &&
541
+ meta.properties[field].kind === ReferenceKind.MANY_TO_MANY &&
542
+ ret[field] &&
543
+ !populate.some(other => other.field === field)) {
544
+ hint.filter = true;
545
+ }
546
+ }
533
547
  return Utils.hasObjectKeys(ret) ? ret : undefined;
534
548
  }
535
549
  /**
@@ -16,6 +16,7 @@ export class EntityFactory {
16
16
  #eventManager;
17
17
  #comparator;
18
18
  #em;
19
+ #recomputeSnapshot = false;
19
20
  constructor(em) {
20
21
  this.#em = em;
21
22
  this.#driver = this.#em.getDriver();
@@ -30,6 +31,8 @@ export class EntityFactory {
30
31
  create(entityName, data, options = {}) {
31
32
  data = Reference.unwrapReference(data);
32
33
  options.initialized ??= true;
34
+ // nested relations created by the hydrator need the same DB-form snapshot as the root (GH #8268)
35
+ options.recomputeSnapshot ??= this.#recomputeSnapshot;
33
36
  if (EntityHelper.isEntity(data)) {
34
37
  return data;
35
38
  }
@@ -356,12 +359,15 @@ export class EntityFactory {
356
359
  }
357
360
  }
358
361
  hydrate(entity, meta, data, options) {
362
+ const recomputeSnapshot = this.#recomputeSnapshot;
363
+ this.#recomputeSnapshot = !!options.recomputeSnapshot;
359
364
  if (options.initialized) {
360
365
  this.#hydrator.hydrate(entity, meta, data, this, 'full', options.newEntity, options.convertCustomTypes, options.schema, this.#driver.getSchemaName(meta, options), options.normalizeAccessors);
361
366
  }
362
367
  else {
363
368
  this.#hydrator.hydrateReference(entity, meta, data, this, options.convertCustomTypes, options.schema, this.#driver.getSchemaName(meta, options), options.normalizeAccessors);
364
369
  }
370
+ this.#recomputeSnapshot = recomputeSnapshot;
365
371
  Utils.keys(data).forEach(key => {
366
372
  helper(entity)?.__loadedProperties.add(key);
367
373
  helper(entity)?.__serializationContext.fields?.add(key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.2.1-dev.2",
3
+ "version": "7.2.1-dev.21",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
package/utils/Utils.js CHANGED
@@ -153,7 +153,7 @@ export function parseJsonSafe(value) {
153
153
  /** Collection of general-purpose utility methods used throughout the ORM. */
154
154
  export class Utils {
155
155
  static PK_SEPARATOR = '~~~';
156
- static #ORM_VERSION = '7.2.1-dev.2';
156
+ static #ORM_VERSION = '7.2.1-dev.21';
157
157
  /** Default session variable name backing an RLS filter argument (`current_setting('mikro.<filter>.<arg>')`). */
158
158
  static getRlsSettingName(filterName, argName) {
159
159
  return `mikro.${filterName}.${argName}`;