@mikro-orm/core 7.0.0-dev.114 → 7.0.0-dev.116

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.
Files changed (55) hide show
  1. package/EntityManager.d.ts +8 -8
  2. package/EntityManager.js +42 -62
  3. package/MikroORM.d.ts +1 -1
  4. package/MikroORM.js +2 -3
  5. package/drivers/DatabaseDriver.d.ts +11 -11
  6. package/drivers/DatabaseDriver.js +7 -8
  7. package/drivers/IDatabaseDriver.d.ts +10 -10
  8. package/entity/Collection.js +5 -5
  9. package/entity/EntityAssigner.js +9 -9
  10. package/entity/EntityFactory.js +14 -17
  11. package/entity/EntityHelper.d.ts +2 -2
  12. package/entity/EntityHelper.js +2 -2
  13. package/entity/EntityLoader.d.ts +3 -3
  14. package/entity/EntityLoader.js +17 -16
  15. package/entity/WrappedEntity.js +1 -1
  16. package/entity/defineEntity.d.ts +11 -11
  17. package/errors.d.ts +8 -8
  18. package/errors.js +14 -13
  19. package/hydration/ObjectHydrator.js +23 -16
  20. package/metadata/EntitySchema.d.ts +5 -5
  21. package/metadata/EntitySchema.js +23 -21
  22. package/metadata/MetadataDiscovery.d.ts +2 -3
  23. package/metadata/MetadataDiscovery.js +117 -90
  24. package/metadata/MetadataProvider.js +2 -0
  25. package/metadata/MetadataStorage.d.ts +13 -6
  26. package/metadata/MetadataStorage.js +64 -19
  27. package/metadata/MetadataValidator.d.ts +2 -2
  28. package/metadata/MetadataValidator.js +22 -28
  29. package/metadata/types.d.ts +3 -3
  30. package/package.json +1 -1
  31. package/serialization/EntitySerializer.d.ts +3 -0
  32. package/serialization/EntitySerializer.js +15 -13
  33. package/serialization/EntityTransformer.js +6 -6
  34. package/serialization/SerializationContext.d.ts +6 -6
  35. package/typings.d.ts +16 -14
  36. package/typings.js +15 -10
  37. package/unit-of-work/ChangeSet.d.ts +2 -3
  38. package/unit-of-work/ChangeSet.js +2 -3
  39. package/unit-of-work/ChangeSetComputer.js +3 -3
  40. package/unit-of-work/ChangeSetPersister.js +14 -14
  41. package/unit-of-work/CommitOrderCalculator.d.ts +12 -10
  42. package/unit-of-work/CommitOrderCalculator.js +13 -13
  43. package/unit-of-work/UnitOfWork.d.ts +3 -3
  44. package/unit-of-work/UnitOfWork.js +46 -45
  45. package/utils/AbstractSchemaGenerator.js +7 -7
  46. package/utils/Configuration.d.ts +0 -5
  47. package/utils/DataloaderUtils.js +13 -11
  48. package/utils/EntityComparator.d.ts +6 -6
  49. package/utils/EntityComparator.js +26 -24
  50. package/utils/QueryHelper.d.ts +5 -5
  51. package/utils/QueryHelper.js +7 -7
  52. package/utils/TransactionManager.js +1 -1
  53. package/utils/Utils.d.ts +1 -1
  54. package/utils/Utils.js +1 -2
  55. package/utils/env-vars.js +0 -1
@@ -19,7 +19,7 @@ export class ChangeSetComputer {
19
19
  this.comparator = this.config.getComparator(this.metadata);
20
20
  }
21
21
  computeChangeSet(entity) {
22
- const meta = this.metadata.get(entity.constructor.name);
22
+ const meta = this.metadata.get(entity.constructor);
23
23
  if (meta.readonly) {
24
24
  return null;
25
25
  }
@@ -91,7 +91,7 @@ export class ChangeSetComputer {
91
91
  computePayload(entity, ignoreUndefined = false) {
92
92
  const data = this.comparator.prepareEntity(entity);
93
93
  const wrapped = helper(entity);
94
- const entityName = wrapped.__meta.className;
94
+ const entityName = wrapped.__meta.class;
95
95
  const originalEntityData = wrapped.__originalEntityData;
96
96
  if (!wrapped.__initialized) {
97
97
  for (const prop of wrapped.__meta.primaryKeys) {
@@ -132,7 +132,7 @@ export class ChangeSetComputer {
132
132
  const targets = Utils.unwrapProperty(changeSet.entity, changeSet.meta, prop);
133
133
  targets.forEach(([target, idx]) => {
134
134
  if (!target.__helper.hasPrimaryKey()) {
135
- Utils.setPayloadProperty(changeSet.payload, this.metadata.find(changeSet.name), prop, target.__helper.__identifier, idx);
135
+ Utils.setPayloadProperty(changeSet.payload, changeSet.meta, prop, target.__helper.__identifier, idx);
136
136
  }
137
137
  });
138
138
  }
@@ -30,7 +30,7 @@ export class ChangeSetPersister {
30
30
  if (!withSchema) {
31
31
  return this.runForEachSchema(changeSets, 'executeInserts', options);
32
32
  }
33
- const meta = this.metadata.find(changeSets[0].name);
33
+ const meta = changeSets[0].meta;
34
34
  changeSets.forEach(changeSet => this.processProperties(changeSet));
35
35
  if (changeSets.length > 1 && this.config.get('useBatchInserts', this.platform.usesBatchInserts())) {
36
36
  return this.persistNewEntities(meta, changeSets, options);
@@ -43,7 +43,7 @@ export class ChangeSetPersister {
43
43
  if (!withSchema) {
44
44
  return this.runForEachSchema(changeSets, 'executeUpdates', options, batched);
45
45
  }
46
- const meta = this.metadata.find(changeSets[0].name);
46
+ const meta = changeSets[0].meta;
47
47
  changeSets.forEach(changeSet => this.processProperties(changeSet));
48
48
  if (batched && changeSets.length > 1 && this.config.get('useBatchUpdates', this.platform.usesBatchUpdates())) {
49
49
  return this.persistManagedEntities(meta, changeSets, options);
@@ -63,7 +63,7 @@ export class ChangeSetPersister {
63
63
  const chunk = changeSets.slice(i, i + size);
64
64
  const pks = chunk.map(cs => cs.getPrimaryKey());
65
65
  options = this.prepareOptions(meta, options);
66
- await this.driver.nativeDelete(meta.root.className, { [pk]: { $in: pks } }, options);
66
+ await this.driver.nativeDelete(meta.root.class, { [pk]: { $in: pks } }, options);
67
67
  }
68
68
  }
69
69
  async runForEachSchema(changeSets, method, options, ...args) {
@@ -99,7 +99,7 @@ export class ChangeSetPersister {
99
99
  }
100
100
  }
101
101
  processProperties(changeSet) {
102
- const meta = this.metadata.find(changeSet.name);
102
+ const meta = changeSet.meta;
103
103
  for (const prop of meta.relations) {
104
104
  this.processProperty(changeSet, prop);
105
105
  }
@@ -112,7 +112,7 @@ export class ChangeSetPersister {
112
112
  options = this.prepareOptions(meta, options, {
113
113
  convertCustomTypes: false,
114
114
  });
115
- const res = await this.driver.nativeInsertMany(meta.className, [changeSet.payload], options);
115
+ const res = await this.driver.nativeInsertMany(meta.class, [changeSet.payload], options);
116
116
  if (!wrapped.hasPrimaryKey()) {
117
117
  this.mapPrimaryKey(meta, res.insertId, changeSet);
118
118
  }
@@ -149,7 +149,7 @@ export class ChangeSetPersister {
149
149
  convertCustomTypes: false,
150
150
  processCollections: false,
151
151
  });
152
- const res = await this.driver.nativeInsertMany(meta.className, changeSets.map(cs => cs.payload), options);
152
+ const res = await this.driver.nativeInsertMany(meta.class, changeSets.map(cs => cs.payload), options);
153
153
  for (let i = 0; i < changeSets.length; i++) {
154
154
  const changeSet = changeSets[i];
155
155
  const wrapped = helper(changeSet.entity);
@@ -167,7 +167,7 @@ export class ChangeSetPersister {
167
167
  }
168
168
  }
169
169
  async persistManagedEntity(changeSet, options) {
170
- const meta = this.metadata.find(changeSet.name);
170
+ const meta = changeSet.meta;
171
171
  const res = await this.updateEntity(meta, changeSet, options);
172
172
  this.checkOptimisticLock(meta, changeSet, res);
173
173
  this.mapReturnedValues(changeSet.entity, changeSet.payload, res.row, meta);
@@ -208,7 +208,7 @@ export class ChangeSetPersister {
208
208
  cond.push(where);
209
209
  payload.push(changeSet.payload);
210
210
  }
211
- const res = await this.driver.nativeUpdateMany(meta.className, cond, payload, options);
211
+ const res = await this.driver.nativeUpdateMany(meta.class, cond, payload, options);
212
212
  const map = new Map();
213
213
  res.rows?.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
214
214
  for (const changeSet of changeSets) {
@@ -260,13 +260,13 @@ export class ChangeSetPersister {
260
260
  convertCustomTypes: false,
261
261
  });
262
262
  if (meta.concurrencyCheckKeys.size === 0 && (!meta.versionProperty || changeSet.entity[meta.versionProperty] == null)) {
263
- return this.driver.nativeUpdate(changeSet.name, cond, changeSet.payload, options);
263
+ return this.driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
264
264
  }
265
265
  if (meta.versionProperty) {
266
266
  cond[meta.versionProperty] = this.platform.quoteVersionValue(changeSet.entity[meta.versionProperty], meta.properties[meta.versionProperty]);
267
267
  }
268
268
  this.checkConcurrencyKeys(meta, changeSet, cond);
269
- return this.driver.nativeUpdate(changeSet.name, cond, changeSet.payload, options);
269
+ return this.driver.nativeUpdate(changeSet.meta.class, cond, changeSet.payload, options);
270
270
  }
271
271
  async checkOptimisticLocks(meta, changeSets, options) {
272
272
  if (meta.concurrencyCheckKeys.size === 0 && (!meta.versionProperty || changeSets.every(cs => cs.entity[meta.versionProperty] == null))) {
@@ -286,7 +286,7 @@ export class ChangeSetPersister {
286
286
  options = this.prepareOptions(meta, options, {
287
287
  fields: primaryKeys,
288
288
  });
289
- const res = await this.driver.find(meta.root.className, { $or }, options);
289
+ const res = await this.driver.find(meta.root.class, { $or }, options);
290
290
  if (res.length !== changeSets.length) {
291
291
  const compare = (a, b, keys) => keys.every(k => a[k] === b[k]);
292
292
  const entity = changeSets.find(cs => {
@@ -356,7 +356,7 @@ export class ChangeSetPersister {
356
356
  options = this.prepareOptions(meta, options, {
357
357
  fields: Utils.unique(reloadProps.map(prop => prop.name)),
358
358
  });
359
- const data = await this.driver.find(meta.className, { [pk]: { $in: pks } }, options);
359
+ const data = await this.driver.find(meta.class, { [pk]: { $in: pks } }, options);
360
360
  const map = new Map();
361
361
  data.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, false, this.platform, true), item));
362
362
  for (const changeSet of changeSets) {
@@ -366,7 +366,7 @@ export class ChangeSetPersister {
366
366
  }
367
367
  }
368
368
  processProperty(changeSet, prop) {
369
- const meta = this.metadata.find(changeSet.name);
369
+ const meta = changeSet.meta;
370
370
  const value = changeSet.payload[prop.name]; // for inline embeddables
371
371
  if (value instanceof EntityIdentifier) {
372
372
  changeSet.payload[prop.name] = value.getValue();
@@ -399,7 +399,7 @@ export class ChangeSetPersister {
399
399
  if ((!this.usesReturningStatement && !upsert) || !row || !Utils.hasObjectKeys(row)) {
400
400
  return;
401
401
  }
402
- const mapped = this.comparator.mapResult(meta.className, row);
402
+ const mapped = this.comparator.mapResult(meta, row);
403
403
  if (entity) {
404
404
  this.hydrator.hydrate(entity, meta, mapped, this.factory, 'full', false, true);
405
405
  }
@@ -1,17 +1,18 @@
1
- import type { Dictionary, EntityProperty } from '../typings.js';
1
+ import type { EntityProperty } from '../typings.js';
2
2
  export declare const enum NodeState {
3
3
  NOT_VISITED = 0,
4
4
  IN_PROGRESS = 1,
5
5
  VISITED = 2
6
6
  }
7
+ type Hash = number;
7
8
  export interface Node {
8
- hash: string;
9
+ hash: Hash;
9
10
  state: NodeState;
10
- dependencies: Dictionary<Edge>;
11
+ dependencies: Map<Hash, Edge>;
11
12
  }
12
13
  export interface Edge {
13
- from: string;
14
- to: string;
14
+ from: Hash;
15
+ to: Hash;
15
16
  weight: number;
16
17
  }
17
18
  /**
@@ -32,23 +33,23 @@ export declare class CommitOrderCalculator {
32
33
  /**
33
34
  * Checks for node existence in graph.
34
35
  */
35
- hasNode(hash: string): boolean;
36
+ hasNode(hash: Hash): boolean;
36
37
  /**
37
38
  * Adds a new node to the graph, assigning its hash.
38
39
  */
39
- addNode(hash: string): void;
40
+ addNode(hash: Hash): void;
40
41
  /**
41
42
  * Adds a new dependency (edge) to the graph using their hashes.
42
43
  */
43
- addDependency(from: string, to: string, weight: number): void;
44
- discoverProperty(prop: EntityProperty, entityName: string): void;
44
+ addDependency(from: Hash, to: Hash, weight: number): void;
45
+ discoverProperty(prop: EntityProperty, entityName: Hash): void;
45
46
  /**
46
47
  * Return a valid order list of all current nodes.
47
48
  * The desired topological sorting is the reverse post order of these searches.
48
49
  *
49
50
  * @internal Highly performance-sensitive method.
50
51
  */
51
- sort(): string[];
52
+ sort(): Hash[];
52
53
  /**
53
54
  * Visit a given node definition for reordering.
54
55
  *
@@ -60,3 +61,4 @@ export declare class CommitOrderCalculator {
60
61
  */
61
62
  private visitOpenNode;
62
63
  }
64
+ export {};
@@ -17,26 +17,26 @@ export var NodeState;
17
17
  */
18
18
  export class CommitOrderCalculator {
19
19
  /** Matrix of nodes, keys are provided hashes and values are the node definition objects. */
20
- nodes = {};
20
+ nodes = new Map();
21
21
  /** Volatile variable holding calculated nodes during sorting process. */
22
22
  sortedNodeList = [];
23
23
  /**
24
24
  * Checks for node existence in graph.
25
25
  */
26
26
  hasNode(hash) {
27
- return hash in this.nodes;
27
+ return this.nodes.has(hash);
28
28
  }
29
29
  /**
30
30
  * Adds a new node to the graph, assigning its hash.
31
31
  */
32
32
  addNode(hash) {
33
- this.nodes[hash] = { hash, state: 0 /* NodeState.NOT_VISITED */, dependencies: {} };
33
+ this.nodes.set(hash, { hash, state: 0 /* NodeState.NOT_VISITED */, dependencies: new Map() });
34
34
  }
35
35
  /**
36
36
  * Adds a new dependency (edge) to the graph using their hashes.
37
37
  */
38
38
  addDependency(from, to, weight) {
39
- this.nodes[from].dependencies[to] = { from, to, weight };
39
+ this.nodes.get(from).dependencies.set(to, { from, to, weight });
40
40
  }
41
41
  discoverProperty(prop, entityName) {
42
42
  const toOneOwner = (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner) || prop.kind === ReferenceKind.MANY_TO_ONE;
@@ -44,8 +44,8 @@ export class CommitOrderCalculator {
44
44
  if (!toOneOwner && !toManyOwner) {
45
45
  return;
46
46
  }
47
- const propertyType = prop.targetMeta?.root.className;
48
- if (!propertyType || !this.hasNode(propertyType)) {
47
+ const propertyType = prop.targetMeta?.root._id;
48
+ if (propertyType == null || !this.hasNode(propertyType)) {
49
49
  return;
50
50
  }
51
51
  this.addDependency(propertyType, entityName, prop.nullable || prop.persist === false ? 0 : 1);
@@ -57,14 +57,14 @@ export class CommitOrderCalculator {
57
57
  * @internal Highly performance-sensitive method.
58
58
  */
59
59
  sort() {
60
- for (const vertex of Object.values(this.nodes)) {
60
+ for (const vertex of this.nodes.values()) {
61
61
  if (vertex.state !== 0 /* NodeState.NOT_VISITED */) {
62
62
  continue;
63
63
  }
64
64
  this.visit(vertex);
65
65
  }
66
66
  const sortedList = this.sortedNodeList.reverse();
67
- this.nodes = {};
67
+ this.nodes = new Map();
68
68
  this.sortedNodeList = [];
69
69
  return sortedList;
70
70
  }
@@ -75,8 +75,8 @@ export class CommitOrderCalculator {
75
75
  */
76
76
  visit(node) {
77
77
  node.state = 1 /* NodeState.IN_PROGRESS */;
78
- for (const edge of Object.values(node.dependencies)) {
79
- const target = this.nodes[edge.to];
78
+ for (const edge of node.dependencies.values()) {
79
+ const target = this.nodes.get(edge.to);
80
80
  switch (target.state) {
81
81
  case 2 /* NodeState.VISITED */: break; // Do nothing, since node was already visited
82
82
  case 1 /* NodeState.IN_PROGRESS */:
@@ -94,11 +94,11 @@ export class CommitOrderCalculator {
94
94
  * Visits all target's dependencies if in cycle with given node
95
95
  */
96
96
  visitOpenNode(node, target, edge) {
97
- if (!target.dependencies[node.hash] || target.dependencies[node.hash].weight >= edge.weight) {
97
+ if (!target.dependencies.has(node.hash) || target.dependencies.get(node.hash).weight >= edge.weight) {
98
98
  return;
99
99
  }
100
- for (const edge of Object.values(target.dependencies)) {
101
- const targetNode = this.nodes[edge.to];
100
+ for (const edge of target.dependencies.values()) {
101
+ const targetNode = this.nodes.get(edge.to);
102
102
  if (targetNode.state === 0 /* NodeState.NOT_VISITED */) {
103
103
  this.visit(targetNode);
104
104
  }
@@ -1,4 +1,4 @@
1
- import type { AnyEntity, EntityData, EntityMetadata, EntityProperty, FilterQuery, Primary } from '../typings.js';
1
+ import type { AnyEntity, EntityData, EntityMetadata, EntityName, EntityProperty, FilterQuery, Primary } from '../typings.js';
2
2
  import { Collection } from '../entity/Collection.js';
3
3
  import { Reference } from '../entity/Reference.js';
4
4
  import { ChangeSet, ChangeSetType } from './ChangeSet.js';
@@ -45,8 +45,8 @@ export declare class UnitOfWork {
45
45
  /**
46
46
  * Returns entity from the identity map. For composite keys, you need to pass an array of PKs in the same order as they are defined in `meta.primaryKeys`.
47
47
  */
48
- getById<T extends object>(entityName: string, id: Primary<T> | Primary<T>[], schema?: string, convertCustomTypes?: boolean): T | undefined;
49
- tryGetById<T extends object>(entityName: string, where: FilterQuery<T>, schema?: string, strict?: boolean): T | null;
48
+ getById<T extends object>(entityName: EntityName<T>, id: Primary<T> | Primary<T>[], schema?: string, convertCustomTypes?: boolean): T | undefined;
49
+ tryGetById<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, schema?: string, strict?: boolean): T | null;
50
50
  /**
51
51
  * Returns map of all managed entities.
52
52
  */
@@ -207,7 +207,7 @@ export class UnitOfWork {
207
207
  if (insideFlush.getStore()) {
208
208
  return false;
209
209
  }
210
- if (this.queuedActions.has(meta.className) || this.queuedActions.has(meta.root.className)) {
210
+ if (this.queuedActions.has(meta.class) || this.queuedActions.has(meta.root.class)) {
211
211
  return true;
212
212
  }
213
213
  if (meta.discriminatorMap && Object.values(meta.discriminatorMap).some(v => this.queuedActions.has(v))) {
@@ -251,7 +251,7 @@ export class UnitOfWork {
251
251
  }
252
252
  const wrapped = helper(entity);
253
253
  this.persistStack.add(entity);
254
- this.queuedActions.add(wrapped.__meta.className);
254
+ this.queuedActions.add(wrapped.__meta.class);
255
255
  this.removeStack.delete(entity);
256
256
  if (!wrapped.__managed && wrapped.hasPrimaryKey()) {
257
257
  this.identityMap.store(entity);
@@ -264,7 +264,7 @@ export class UnitOfWork {
264
264
  // allow removing not managed entities if they are not part of the persist stack
265
265
  if (helper(entity).__managed || !this.persistStack.has(entity)) {
266
266
  this.removeStack.add(entity);
267
- this.queuedActions.add(helper(entity).__meta.className);
267
+ this.queuedActions.add(helper(entity).__meta.class);
268
268
  }
269
269
  else {
270
270
  this.persistStack.delete(entity);
@@ -355,10 +355,10 @@ export class UnitOfWork {
355
355
  }
356
356
  }
357
357
  async lock(entity, options) {
358
- if (!this.getById(entity.constructor.name, helper(entity).__primaryKeys, helper(entity).__schema)) {
358
+ if (!this.getById(entity.constructor, helper(entity).__primaryKeys, helper(entity).__schema)) {
359
359
  throw ValidationError.entityNotManaged(entity);
360
360
  }
361
- const meta = this.metadata.find(entity.constructor.name);
361
+ const meta = this.metadata.find(entity.constructor);
362
362
  if (options.lockMode === LockMode.OPTIMISTIC) {
363
363
  await this.lockOptimistic(entity, meta, options.lockVersion);
364
364
  }
@@ -382,7 +382,7 @@ export class UnitOfWork {
382
382
  if (Utils.isCollection(rel)) {
383
383
  rel.removeWithoutPropagation(entity);
384
384
  }
385
- else if (rel && (prop.mapToPk ? helper(this.em.getReference(prop.type, rel)).getSerializedPrimaryKey() === serializedPK : rel === entity)) {
385
+ else if (rel && (prop.mapToPk ? helper(this.em.getReference(prop.targetMeta.class, rel)).getSerializedPrimaryKey() === serializedPK : rel === entity)) {
386
386
  if (prop.formula) {
387
387
  delete referrer[prop.name];
388
388
  }
@@ -424,13 +424,13 @@ export class UnitOfWork {
424
424
  const inserts = {};
425
425
  for (const cs of this.changeSets.values()) {
426
426
  if (cs.type === ChangeSetType.CREATE) {
427
- inserts[cs.meta.className] ??= [];
428
- inserts[cs.meta.className].push(cs);
427
+ inserts[cs.meta.uniqueName] ??= [];
428
+ inserts[cs.meta.uniqueName].push(cs);
429
429
  }
430
430
  }
431
431
  for (const cs of this.changeSets.values()) {
432
432
  if (cs.type === ChangeSetType.UPDATE) {
433
- this.findEarlyUpdates(cs, inserts[cs.meta.className]);
433
+ this.findEarlyUpdates(cs, inserts[cs.meta.uniqueName]);
434
434
  }
435
435
  }
436
436
  for (const entity of this.removeStack) {
@@ -441,7 +441,7 @@ export class UnitOfWork {
441
441
  }
442
442
  const deletePkHash = [wrapped.getSerializedPrimaryKey(), ...this.expandUniqueProps(entity)];
443
443
  let type = ChangeSetType.DELETE;
444
- for (const cs of inserts[wrapped.__meta.className] ?? []) {
444
+ for (const cs of inserts[wrapped.__meta.uniqueName] ?? []) {
445
445
  if (deletePkHash.some(hash => hash === cs.getSerializedPrimaryKey() || this.expandUniqueProps(cs.entity).find(child => hash === child))) {
446
446
  type = ChangeSetType.DELETE_EARLY;
447
447
  }
@@ -460,7 +460,7 @@ export class UnitOfWork {
460
460
  }
461
461
  for (const cs of this.changeSets.values()) {
462
462
  for (const prop of props) {
463
- if (prop.name in cs.payload && cs.rootName === changeSet.rootName && cs.type === changeSet.type) {
463
+ if (prop.name in cs.payload && cs.rootMeta === changeSet.rootMeta && cs.type === changeSet.type) {
464
464
  conflicts = true;
465
465
  if (changeSet.payload[prop.name] == null) {
466
466
  type = ChangeSetType.UPDATE_EARLY;
@@ -479,9 +479,10 @@ export class UnitOfWork {
479
479
  }
480
480
  scheduleOrphanRemoval(entity, visited) {
481
481
  if (entity) {
482
- helper(entity).__em = this.em;
482
+ const wrapped = helper(entity);
483
+ wrapped.__em = this.em;
483
484
  this.orphanRemoveStack.add(entity);
484
- this.queuedActions.add(entity.__meta.className);
485
+ this.queuedActions.add(wrapped.__meta.class);
485
486
  this.cascade(entity, Cascade.SCHEDULE_ORPHAN_REMOVAL, visited);
486
487
  }
487
488
  }
@@ -630,7 +631,7 @@ export class UnitOfWork {
630
631
  const copy = this.comparator.prepareEntity(changeSet.entity);
631
632
  await this.eventManager.dispatchEvent(type, { entity: changeSet.entity, meta, em: this.em, changeSet });
632
633
  const current = this.comparator.prepareEntity(changeSet.entity);
633
- const diff = this.comparator.diffEntities(changeSet.name, copy, current);
634
+ const diff = this.comparator.diffEntities(changeSet.meta.class, copy, current);
634
635
  Object.assign(changeSet.payload, diff);
635
636
  const wrapped = helper(changeSet.entity);
636
637
  if (wrapped.__identifier) {
@@ -739,26 +740,26 @@ export class UnitOfWork {
739
740
  }
740
741
  fixMissingReference(entity, prop) {
741
742
  const reference = entity[prop.name];
742
- const kind = Reference.unwrapReference(reference);
743
- if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && kind && !prop.mapToPk) {
744
- if (!Utils.isEntity(kind)) {
745
- entity[prop.name] = this.em.getReference(prop.type, kind, { wrapped: !!prop.ref });
743
+ const target = Reference.unwrapReference(reference);
744
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) && target && !prop.mapToPk) {
745
+ if (!Utils.isEntity(target)) {
746
+ entity[prop.name] = this.em.getReference(prop.targetMeta.class, target, { wrapped: !!prop.ref });
746
747
  }
747
- else if (!helper(kind).__initialized && !helper(kind).__em) {
748
- const pk = helper(kind).getPrimaryKey();
749
- entity[prop.name] = this.em.getReference(prop.type, pk, { wrapped: !!prop.ref });
748
+ else if (!helper(target).__initialized && !helper(target).__em) {
749
+ const pk = helper(target).getPrimaryKey();
750
+ entity[prop.name] = this.em.getReference(prop.targetMeta.class, pk, { wrapped: !!prop.ref });
750
751
  }
751
752
  }
752
- // perf: set the `Collection._property` to skip the getter, as it can be slow when there is a lot of relations
753
- if (Utils.isCollection(kind)) {
754
- kind.property = prop;
753
+ // perf: set the `Collection._property` to skip the getter, as it can be slow when there are a lot of relations
754
+ if (Utils.isCollection(target)) {
755
+ target.property = prop;
755
756
  }
756
757
  const isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
757
- if (isCollection && Array.isArray(kind)) {
758
+ if (isCollection && Array.isArray(target)) {
758
759
  const collection = new Collection(entity);
759
760
  collection.property = prop;
760
761
  entity[prop.name] = collection;
761
- collection.set(kind);
762
+ collection.set(target);
762
763
  }
763
764
  }
764
765
  async persistToDatabase(groups, ctx) {
@@ -768,30 +769,30 @@ export class UnitOfWork {
768
769
  const commitOrder = this.getCommitOrder();
769
770
  const commitOrderReversed = [...commitOrder].reverse();
770
771
  // early delete - when we recreate entity in the same UoW, we need to issue those delete queries before inserts
771
- for (const name of commitOrderReversed) {
772
- await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE_EARLY].get(name) ?? [], ctx);
772
+ for (const meta of commitOrderReversed) {
773
+ await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE_EARLY].get(meta) ?? [], ctx);
773
774
  }
774
775
  // early update - when we recreate entity in the same UoW, we need to issue those delete queries before inserts
775
- for (const name of commitOrder) {
776
- await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE_EARLY].get(name) ?? [], ctx);
776
+ for (const meta of commitOrder) {
777
+ await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE_EARLY].get(meta) ?? [], ctx);
777
778
  }
778
779
  // extra updates
779
780
  await this.commitExtraUpdates(ChangeSetType.UPDATE_EARLY, ctx);
780
781
  // create
781
- for (const name of commitOrder) {
782
- await this.commitCreateChangeSets(groups[ChangeSetType.CREATE].get(name) ?? [], ctx);
782
+ for (const meta of commitOrder) {
783
+ await this.commitCreateChangeSets(groups[ChangeSetType.CREATE].get(meta) ?? [], ctx);
783
784
  }
784
785
  // update
785
- for (const name of commitOrder) {
786
- await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE].get(name) ?? [], ctx);
786
+ for (const meta of commitOrder) {
787
+ await this.commitUpdateChangeSets(groups[ChangeSetType.UPDATE].get(meta) ?? [], ctx);
787
788
  }
788
789
  // extra updates
789
790
  await this.commitExtraUpdates(ChangeSetType.UPDATE, ctx);
790
791
  // collection updates
791
792
  await this.commitCollectionUpdates(ctx);
792
793
  // delete - entity deletions need to be in reverse commit order
793
- for (const name of commitOrderReversed) {
794
- await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE].get(name) ?? [], ctx);
794
+ for (const meta of commitOrderReversed) {
795
+ await this.commitDeleteChangeSets(groups[ChangeSetType.DELETE].get(meta) ?? [], ctx);
795
796
  }
796
797
  // take snapshots of all persisted collections
797
798
  const visited = new Set();
@@ -960,10 +961,10 @@ export class UnitOfWork {
960
961
  };
961
962
  for (const cs of this.changeSets.values()) {
962
963
  const group = groups[cs.type];
963
- const classGroup = group.get(cs.rootName) ?? [];
964
+ const classGroup = group.get(cs.rootMeta) ?? [];
964
965
  classGroup.push(cs);
965
- if (!group.has(cs.rootName)) {
966
- group.set(cs.rootName, classGroup);
966
+ if (!group.has(cs.rootMeta)) {
967
+ group.set(cs.rootMeta, classGroup);
967
968
  }
968
969
  }
969
970
  return groups;
@@ -971,14 +972,14 @@ export class UnitOfWork {
971
972
  getCommitOrder() {
972
973
  const calc = new CommitOrderCalculator();
973
974
  const set = new Set();
974
- this.changeSets.forEach(cs => set.add(cs.rootName));
975
- set.forEach(entityName => calc.addNode(entityName));
976
- for (const entityName of set) {
977
- for (const prop of this.metadata.find(entityName).props) {
978
- calc.discoverProperty(prop, entityName);
975
+ this.changeSets.forEach(cs => set.add(cs.rootMeta));
976
+ set.forEach(meta => calc.addNode(meta._id));
977
+ for (const meta of set) {
978
+ for (const prop of meta.relations) {
979
+ calc.discoverProperty(prop, meta._id);
979
980
  }
980
981
  }
981
- return calc.sort();
982
+ return calc.sort().map(id => this.metadata.getById(id));
982
983
  }
983
984
  resetTransaction(oldTx) {
984
985
  if (oldTx) {
@@ -40,7 +40,7 @@ export class AbstractSchemaGenerator {
40
40
  }
41
41
  async clear(options) {
42
42
  for (const meta of this.getOrderedMetadata(options?.schema).reverse()) {
43
- await this.driver.nativeDelete(meta.className, {}, options);
43
+ await this.driver.nativeDelete(meta.class, {}, options);
44
44
  }
45
45
  if (options?.clearIdentityMap ?? true) {
46
46
  this.clearIdentityMap();
@@ -90,21 +90,21 @@ export class AbstractSchemaGenerator {
90
90
  this.notImplemented();
91
91
  }
92
92
  getOrderedMetadata(schema) {
93
- const metadata = Object.values(this.metadata.getAll()).filter(meta => {
94
- const isRootEntity = meta.root.className === meta.className;
93
+ const metadata = [...this.metadata.getAll().values()].filter(meta => {
94
+ const isRootEntity = meta.root.class === meta.class;
95
95
  return isRootEntity && !meta.embeddable && !meta.virtual;
96
96
  });
97
97
  const calc = new CommitOrderCalculator();
98
- metadata.forEach(meta => calc.addNode(meta.root.className));
98
+ metadata.forEach(meta => calc.addNode(meta.root._id));
99
99
  let meta = metadata.pop();
100
100
  while (meta) {
101
- for (const prop of meta.props) {
102
- calc.discoverProperty(prop, meta.root.className);
101
+ for (const prop of meta.relations) {
102
+ calc.discoverProperty(prop, meta.root._id);
103
103
  }
104
104
  meta = metadata.pop();
105
105
  }
106
106
  return calc.sort()
107
- .map(cls => this.metadata.find(cls))
107
+ .map(cls => this.metadata.getById(cls))
108
108
  .filter(meta => {
109
109
  const targetSchema = meta.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
110
110
  return schema ? [schema, '*'].includes(targetSchema) : meta.schema !== '*';
@@ -402,11 +402,6 @@ export interface MetadataDiscoveryOptions {
402
402
  * @default true
403
403
  */
404
404
  checkDuplicateFieldNames?: boolean;
405
- /**
406
- * Check for duplicate entities and throw an error if found.
407
- * @default true
408
- */
409
- checkDuplicateEntities?: boolean;
410
405
  /**
411
406
  * Check for composite primary keys marked as `persist: false` and throw an error if found.
412
407
  * @default true