@mikro-orm/core 7.0.16-dev.14 → 7.0.16-dev.15

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.
package/EntityManager.js CHANGED
@@ -1,4 +1,4 @@
1
- import { getOnConflictReturningFields, getWhereCondition } from './utils/upsert-utils.js';
1
+ import { getOnConflictReturningFields, getWhereCondition, resetUntouchedCollections } from './utils/upsert-utils.js';
2
2
  import { Utils } from './utils/Utils.js';
3
3
  import { Cursor } from './utils/Cursor.js';
4
4
  import { QueryHelper } from './utils/QueryHelper.js';
@@ -865,6 +865,7 @@ export class EntityManager {
865
865
  em.getHydrator().hydrate(entity, meta, data2, em.#entityFactory, 'full', false, true);
866
866
  }
867
867
  // recompute the data as there might be some values missing (e.g. those with db column defaults)
868
+ resetUntouchedCollections(meta, entity);
868
869
  const snapshot = this.#comparator.prepareEntity(entity);
869
870
  em.#unitOfWork.register(entity, snapshot, { refresh: true });
870
871
  if (em.eventManager.hasListeners(EventType.afterUpsert, meta)) {
@@ -1096,6 +1097,7 @@ export class EntityManager {
1096
1097
  }
1097
1098
  for (const [entity] of entities) {
1098
1099
  // recompute the data as there might be some values missing (e.g. those with db column defaults)
1100
+ resetUntouchedCollections(meta, entity);
1099
1101
  const snapshot = this.#comparator.prepareEntity(entity);
1100
1102
  em.#unitOfWork.register(entity, snapshot, { refresh: true });
1101
1103
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/core",
3
- "version": "7.0.16-dev.14",
3
+ "version": "7.0.16-dev.15",
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
@@ -141,7 +141,7 @@ export function parseJsonSafe(value) {
141
141
  /** Collection of general-purpose utility methods used throughout the ORM. */
142
142
  export class Utils {
143
143
  static PK_SEPARATOR = '~~~';
144
- static #ORM_VERSION = '7.0.16-dev.14';
144
+ static #ORM_VERSION = '7.0.16-dev.15';
145
145
  /**
146
146
  * Checks if the argument is instance of `Object`. Returns false for arrays.
147
147
  */
@@ -10,3 +10,5 @@ export declare function getWhereCondition<T extends object>(meta: EntityMetadata
10
10
  where: FilterQuery<T>;
11
11
  propIndex: number | false;
12
12
  };
13
+ /** @internal */
14
+ export declare function resetUntouchedCollections<Entity extends object>(meta: EntityMetadata<Entity>, entity: Entity): void;
@@ -1,5 +1,8 @@
1
1
  import { isRaw } from '../utils/RawQueryFragment.js';
2
2
  import { Utils } from './Utils.js';
3
+ import { ReferenceKind } from '../enums.js';
4
+ import { Collection } from '../entity/Collection.js';
5
+ import { helper } from '../entity/wrap.js';
3
6
  function expandEmbeddedProperties(prop, key) {
4
7
  if (prop.object) {
5
8
  return [prop.name];
@@ -52,7 +55,9 @@ export function getOnConflictFields(meta, data, uniqueFields, options) {
52
55
  });
53
56
  }
54
57
  const keys = Object.keys(data).flatMap(f => {
55
- if (!(Array.isArray(uniqueFields) && !uniqueFields.includes(f))) {
58
+ // skip explicitly listed unique fields; for raw onConflictFields we can't introspect the
59
+ // fragment, so merge all data keys (the user is responsible for not corrupting them).
60
+ if (Array.isArray(uniqueFields) && uniqueFields.includes(f)) {
56
61
  return [];
57
62
  }
58
63
  const prop = meta?.properties[f];
@@ -142,3 +147,23 @@ export function getWhereCondition(meta, onConflictFields, data, where) {
142
147
  }
143
148
  return { where, propIndex };
144
149
  }
150
+ /** @internal */
151
+ export function resetUntouchedCollections(meta, entity) {
152
+ // for entities passed in via `em.create()` and then upserted, collection-kind relations
153
+ // were initialized as empty-but-initialized by the hydrator (newEntity=true). once the
154
+ // upsert resolves the entity to a possibly existing row, that state is stale and would
155
+ // cause `em.populate()` to skip those collections. replace them with a fresh
156
+ // uninitialized collection so populate can load them.
157
+ if (helper(entity).__originalEntityData) {
158
+ return;
159
+ }
160
+ for (const prop of meta.relations) {
161
+ if (prop.kind !== ReferenceKind.MANY_TO_MANY && prop.kind !== ReferenceKind.ONE_TO_MANY) {
162
+ continue;
163
+ }
164
+ const collection = entity[prop.name];
165
+ if (Utils.isCollection(collection) && collection.isInitialized() && !collection.isDirty()) {
166
+ Collection.create(entity, prop.name, undefined, false);
167
+ }
168
+ }
169
+ }