@mikro-orm/core 7.0.0-dev.5 → 7.0.0-dev.51

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 (115) hide show
  1. package/EntityManager.d.ts +81 -27
  2. package/EntityManager.js +287 -175
  3. package/MikroORM.d.ts +6 -6
  4. package/MikroORM.js +31 -74
  5. package/README.md +3 -2
  6. package/cache/FileCacheAdapter.d.ts +2 -1
  7. package/cache/FileCacheAdapter.js +6 -4
  8. package/connections/Connection.d.ts +9 -5
  9. package/connections/Connection.js +16 -13
  10. package/decorators/Embedded.d.ts +5 -11
  11. package/decorators/Entity.d.ts +18 -3
  12. package/decorators/Indexed.d.ts +2 -2
  13. package/decorators/ManyToMany.d.ts +2 -0
  14. package/decorators/ManyToOne.d.ts +4 -0
  15. package/decorators/OneToOne.d.ts +4 -0
  16. package/decorators/Property.d.ts +53 -9
  17. package/decorators/Transactional.d.ts +1 -0
  18. package/decorators/Transactional.js +3 -3
  19. package/decorators/index.d.ts +1 -1
  20. package/drivers/DatabaseDriver.d.ts +10 -5
  21. package/drivers/DatabaseDriver.js +4 -4
  22. package/drivers/IDatabaseDriver.d.ts +28 -4
  23. package/entity/ArrayCollection.d.ts +6 -4
  24. package/entity/ArrayCollection.js +26 -9
  25. package/entity/BaseEntity.d.ts +0 -1
  26. package/entity/BaseEntity.js +0 -3
  27. package/entity/Collection.d.ts +3 -4
  28. package/entity/Collection.js +37 -17
  29. package/entity/EntityAssigner.d.ts +1 -1
  30. package/entity/EntityAssigner.js +9 -1
  31. package/entity/EntityFactory.d.ts +7 -0
  32. package/entity/EntityFactory.js +29 -11
  33. package/entity/EntityHelper.js +25 -8
  34. package/entity/EntityLoader.d.ts +5 -4
  35. package/entity/EntityLoader.js +69 -36
  36. package/entity/EntityRepository.d.ts +1 -1
  37. package/entity/EntityValidator.js +1 -1
  38. package/entity/Reference.d.ts +9 -7
  39. package/entity/Reference.js +30 -3
  40. package/entity/WrappedEntity.d.ts +0 -2
  41. package/entity/WrappedEntity.js +1 -5
  42. package/entity/defineEntity.d.ts +555 -0
  43. package/entity/defineEntity.js +529 -0
  44. package/entity/index.d.ts +2 -0
  45. package/entity/index.js +2 -0
  46. package/entity/utils.d.ts +7 -0
  47. package/entity/utils.js +15 -3
  48. package/enums.d.ts +16 -3
  49. package/enums.js +13 -0
  50. package/errors.d.ts +6 -1
  51. package/errors.js +14 -4
  52. package/events/EventSubscriber.d.ts +3 -1
  53. package/hydration/ObjectHydrator.d.ts +4 -4
  54. package/hydration/ObjectHydrator.js +35 -24
  55. package/index.d.ts +2 -1
  56. package/index.js +1 -1
  57. package/logging/DefaultLogger.d.ts +1 -1
  58. package/logging/SimpleLogger.d.ts +1 -1
  59. package/metadata/EntitySchema.d.ts +8 -4
  60. package/metadata/EntitySchema.js +39 -19
  61. package/metadata/MetadataDiscovery.d.ts +4 -4
  62. package/metadata/MetadataDiscovery.js +139 -122
  63. package/metadata/MetadataStorage.js +1 -1
  64. package/metadata/MetadataValidator.js +4 -3
  65. package/naming-strategy/AbstractNamingStrategy.d.ts +5 -1
  66. package/naming-strategy/AbstractNamingStrategy.js +7 -1
  67. package/naming-strategy/NamingStrategy.d.ts +11 -1
  68. package/package.json +5 -5
  69. package/platforms/Platform.d.ts +5 -3
  70. package/platforms/Platform.js +4 -8
  71. package/serialization/EntitySerializer.d.ts +2 -0
  72. package/serialization/EntitySerializer.js +23 -5
  73. package/serialization/EntityTransformer.js +16 -6
  74. package/serialization/SerializationContext.js +14 -11
  75. package/types/BigIntType.d.ts +9 -6
  76. package/types/BigIntType.js +3 -0
  77. package/types/BooleanType.d.ts +1 -1
  78. package/types/DecimalType.d.ts +6 -4
  79. package/types/DecimalType.js +1 -1
  80. package/types/DoubleType.js +1 -1
  81. package/types/JsonType.d.ts +1 -1
  82. package/types/JsonType.js +7 -2
  83. package/types/Type.d.ts +2 -1
  84. package/types/Type.js +1 -1
  85. package/types/index.d.ts +1 -1
  86. package/typings.d.ts +89 -49
  87. package/typings.js +31 -31
  88. package/unit-of-work/ChangeSetComputer.js +8 -3
  89. package/unit-of-work/ChangeSetPersister.d.ts +4 -2
  90. package/unit-of-work/ChangeSetPersister.js +37 -16
  91. package/unit-of-work/UnitOfWork.d.ts +8 -1
  92. package/unit-of-work/UnitOfWork.js +110 -53
  93. package/utils/AbstractSchemaGenerator.js +3 -1
  94. package/utils/Configuration.d.ts +200 -183
  95. package/utils/Configuration.js +137 -144
  96. package/utils/ConfigurationLoader.d.ts +9 -22
  97. package/utils/ConfigurationLoader.js +49 -72
  98. package/utils/Cursor.d.ts +3 -3
  99. package/utils/Cursor.js +3 -0
  100. package/utils/DataloaderUtils.d.ts +7 -2
  101. package/utils/DataloaderUtils.js +38 -7
  102. package/utils/EntityComparator.d.ts +6 -2
  103. package/utils/EntityComparator.js +104 -58
  104. package/utils/QueryHelper.d.ts +9 -1
  105. package/utils/QueryHelper.js +66 -5
  106. package/utils/RawQueryFragment.d.ts +36 -4
  107. package/utils/RawQueryFragment.js +34 -13
  108. package/utils/TransactionManager.d.ts +65 -0
  109. package/utils/TransactionManager.js +223 -0
  110. package/utils/Utils.d.ts +13 -11
  111. package/utils/Utils.js +82 -55
  112. package/utils/index.d.ts +1 -0
  113. package/utils/index.js +1 -0
  114. package/utils/upsert-utils.d.ts +7 -2
  115. package/utils/upsert-utils.js +52 -1
package/typings.d.ts CHANGED
@@ -19,7 +19,7 @@ import type { RawQueryFragment } from './utils/RawQueryFragment.js';
19
19
  import type { EntityManager } from './EntityManager.js';
20
20
  import type { EmbeddedPrefixMode } from './decorators/Embedded.js';
21
21
  import type { EventSubscriber } from './events/EventSubscriber.js';
22
- import type { FindOneOptions, FindOptions, LoadHint } from './drivers/IDatabaseDriver.js';
22
+ import type { FilterOptions, FindOneOptions, FindOptions, LoadHint } from './drivers/IDatabaseDriver.js';
23
23
  export type Constructor<T = unknown> = new (...args: any[]) => T;
24
24
  export type Dictionary<T = any> = {
25
25
  [k: string]: T;
@@ -52,18 +52,34 @@ export declare const OptionalProps: unique symbol;
52
52
  export declare const EagerProps: unique symbol;
53
53
  export declare const HiddenProps: unique symbol;
54
54
  export declare const Config: unique symbol;
55
- declare const __optional: unique symbol;
56
- declare const __hidden: unique symbol;
57
- declare const __config: unique symbol;
58
- export type Opt<T = unknown> = T & {
59
- [__optional]?: 1;
60
- };
61
- export type Hidden<T = unknown> = T & {
62
- [__hidden]?: 1;
63
- };
64
- export type DefineConfig<T extends TypeConfig> = T & {
65
- [__config]?: 1;
66
- };
55
+ export type Opt<T = unknown> = T & Opt.Brand;
56
+ export declare namespace Opt {
57
+ const __optional: unique symbol;
58
+ interface Brand {
59
+ [__optional]?: 1;
60
+ }
61
+ }
62
+ export type RequiredNullable<T = never> = (T & RequiredNullable.Brand) | null;
63
+ export declare namespace RequiredNullable {
64
+ const __requiredNullable: unique symbol;
65
+ interface Brand {
66
+ [__requiredNullable]?: 1;
67
+ }
68
+ }
69
+ export type Hidden<T = unknown> = T & Hidden.Brand;
70
+ export declare namespace Hidden {
71
+ const __hidden: unique symbol;
72
+ interface Brand {
73
+ [__hidden]?: 1;
74
+ }
75
+ }
76
+ export type DefineConfig<T extends TypeConfig> = T & DefineConfig.Brand;
77
+ export declare namespace DefineConfig {
78
+ const __config: unique symbol;
79
+ interface Brand {
80
+ [__config]?: 1;
81
+ }
82
+ }
67
83
  export type CleanTypeConfig<T> = Compute<Pick<T, Extract<keyof T, keyof TypeConfig>>>;
68
84
  export interface TypeConfig {
69
85
  forceObject?: boolean;
@@ -75,13 +91,14 @@ type PrimaryPropToType<T, Keys extends (keyof T)[]> = {
75
91
  type ReadonlyPrimary<T> = T extends any[] ? Readonly<T> : T;
76
92
  export type Primary<T> = IsAny<T> extends true ? any : T extends {
77
93
  [PrimaryKeyProp]?: infer PK;
78
- } ? (PK extends keyof T ? ReadonlyPrimary<UnwrapPrimary<T[PK]>> : (PK extends (keyof T)[] ? ReadonlyPrimary<PrimaryPropToType<T, PK>> : PK)) : T extends {
94
+ } ? PK extends undefined ? Omit<T, typeof PrimaryKeyProp> : PK extends keyof T ? ReadonlyPrimary<UnwrapPrimary<T[PK]>> : PK extends (keyof T)[] ? ReadonlyPrimary<PrimaryPropToType<T, PK>> : PK : T extends {
79
95
  _id?: infer PK;
80
96
  } ? ReadonlyPrimary<PK> | string : T extends {
81
- uuid?: infer PK;
82
- } ? ReadonlyPrimary<PK> : T extends {
83
97
  id?: infer PK;
98
+ } ? ReadonlyPrimary<PK> : T extends {
99
+ uuid?: infer PK;
84
100
  } ? ReadonlyPrimary<PK> : T;
101
+ /** @internal */
85
102
  export type PrimaryProperty<T> = T extends {
86
103
  [PrimaryKeyProp]?: infer PK;
87
104
  } ? (PK extends keyof T ? PK : (PK extends any[] ? PK[number] : never)) : T extends {
@@ -89,10 +106,10 @@ export type PrimaryProperty<T> = T extends {
89
106
  } ? (T extends {
90
107
  id?: any;
91
108
  } ? 'id' | '_id' : '_id') : T extends {
92
- uuid?: any;
93
- } ? 'uuid' : T extends {
94
109
  id?: any;
95
- } ? 'id' : never;
110
+ } ? 'id' : T extends {
111
+ uuid?: any;
112
+ } ? 'uuid' : never;
96
113
  export type IPrimaryKeyValue = number | string | bigint | Date | {
97
114
  toHexString(): string;
98
115
  };
@@ -143,7 +160,6 @@ export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T
143
160
  export type QBFilterQuery<T = any> = ObjectQuery<T> | Dictionary;
144
161
  export interface IWrappedEntity<Entity extends object> {
145
162
  isInitialized(): boolean;
146
- isTouched(): boolean;
147
163
  isManaged(): boolean;
148
164
  populated(populated?: boolean): void;
149
165
  populate<Hint extends string = never>(populate: AutoPath<Entity, Hint>[] | false, options?: EntityLoaderOptions<Entity>): Promise<Loaded<Entity, Hint>>;
@@ -174,10 +190,9 @@ export interface IWrappedEntityInternal<Entity extends object> extends IWrappedE
174
190
  __factory: EntityFactory;
175
191
  __hydrator: IHydrator;
176
192
  __initialized: boolean;
177
- __touched: boolean;
178
193
  __originalEntityData?: EntityData<Entity>;
179
194
  __loadedProperties: Set<string>;
180
- __identifier?: EntityIdentifier;
195
+ __identifier?: EntityIdentifier | EntityIdentifier[];
181
196
  __managed: boolean;
182
197
  __processing: boolean;
183
198
  __schema?: string;
@@ -197,16 +212,12 @@ export type AnyEntity<T = any> = Partial<T>;
197
212
  export type EntityClass<T> = Function & {
198
213
  prototype: T;
199
214
  };
200
- export type EntityClassGroup<T> = {
201
- entity: EntityClass<T>;
202
- schema: EntityMetadata<T> | EntitySchema<T>;
203
- };
204
215
  export type EntityName<T> = string | EntityClass<T> | EntitySchema<T, any> | {
205
216
  name: string;
206
217
  };
207
218
  export type GetRepository<Entity extends {
208
219
  [k: PropertyKey]: any;
209
- }, Fallback> = Entity[typeof EntityRepositoryType] extends EntityRepository<Entity> | undefined ? NonNullable<Entity[typeof EntityRepositoryType]> : Fallback;
220
+ }, Fallback> = Entity[typeof EntityRepositoryType] extends EntityRepository<any> | undefined ? NonNullable<Entity[typeof EntityRepositoryType]> : Fallback;
210
221
  export type EntityDataPropValue<T> = T | Primary<T>;
211
222
  type ExpandEntityProp<T, C extends boolean = false> = T extends Record<string, any> ? {
212
223
  [K in keyof T as CleanKeys<T, K>]?: EntityDataProp<ExpandProperty<T[K]>, C> | EntityDataPropValue<ExpandProperty<T[K]>> | null;
@@ -217,14 +228,17 @@ type ExpandRequiredEntityPropObject<T, I = never, C extends boolean = false> = {
217
228
  } & {
218
229
  [K in keyof T as OptionalKeys<T, K, I>]?: RequiredEntityDataProp<ExpandProperty<T[K]>, T, C> | EntityDataPropValue<ExpandProperty<T[K]>> | null | undefined;
219
230
  };
231
+ type NonArrayObject = object & {
232
+ [Symbol.iterator]?: never;
233
+ };
220
234
  export type EntityDataProp<T, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends {
221
235
  __runtime?: infer Runtime;
222
236
  __raw?: infer Raw;
223
- } ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? EntityDataNested<U, C> : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends Collection<infer U, any> ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : T extends readonly (infer U)[] ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
224
- export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : T extends Scalar ? T : T extends {
237
+ } ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? EntityDataNested<U, C> : T extends ScalarReference<infer U> ? EntityDataProp<U, C> : T extends Collection<infer U, any> ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | EntityDataNested<U, C> | EntityDataNested<U, C>[] : U[] | EntityDataNested<U, C>[] : EntityDataNested<T, C>;
238
+ export type RequiredEntityDataProp<T, O, C extends boolean> = T extends Date ? string | Date : Exclude<T, null> extends RequiredNullable.Brand ? T | null : T extends Scalar ? T : T extends {
225
239
  __runtime?: infer Runtime;
226
240
  __raw?: infer Raw;
227
- } ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? RequiredEntityDataNested<U, O, C> : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends Collection<infer U, any> ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : T extends readonly (infer U)[] ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
241
+ } ? (C extends true ? Raw : Runtime) : T extends Reference<infer U> ? RequiredEntityDataNested<U, O, C> : T extends ScalarReference<infer U> ? RequiredEntityDataProp<U, O, C> : T extends Collection<infer U, any> ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : T extends readonly (infer U)[] ? U extends NonArrayObject ? U | U[] | RequiredEntityDataNested<U, O, C> | RequiredEntityDataNested<U, O, C>[] : U[] | RequiredEntityDataNested<U, O, C>[] : RequiredEntityDataNested<T, O, C>;
228
242
  export type EntityDataNested<T, C extends boolean = false> = T extends undefined ? never : T extends any[] ? Readonly<T> : EntityData<T, C> | ExpandEntityProp<T, C>;
229
243
  type EntityDataItem<T, C extends boolean> = C extends false ? T | EntityDataProp<T, C> | null : EntityDataProp<T, C> | null;
230
244
  export type RequiredEntityDataNested<T, O, C extends boolean> = T extends any[] ? Readonly<T> : RequiredEntityData<T, O> | ExpandRequiredEntityProp<T, O, C>;
@@ -236,7 +250,10 @@ type ExplicitlyOptionalProps<T> = (T extends {
236
250
  type NullableKeys<T, V = null> = {
237
251
  [K in keyof T]: V extends T[K] ? K : never;
238
252
  }[keyof T];
239
- type ProbablyOptionalProps<T> = PrimaryProperty<T> | ExplicitlyOptionalProps<T> | NonNullable<NullableKeys<T, null | undefined>>;
253
+ type RequiredNullableKeys<T> = {
254
+ [K in keyof T]: Exclude<T[K], null> extends RequiredNullable.Brand ? K : never;
255
+ }[keyof T];
256
+ type ProbablyOptionalProps<T> = PrimaryProperty<T> | ExplicitlyOptionalProps<T> | Exclude<NonNullable<NullableKeys<T, null | undefined>>, RequiredNullableKeys<T>>;
240
257
  type IsOptional<T, K extends keyof T, I> = T[K] extends Collection<any, any> ? true : ExtractType<T[K]> extends I ? true : K extends ProbablyOptionalProps<T> ? true : false;
241
258
  type RequiredKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? CleanKeys<T, K> : never;
242
259
  type OptionalKeys<T, K extends keyof T, I> = IsOptional<T, K, I> extends false ? never : CleanKeys<T, K>;
@@ -283,7 +300,7 @@ type PrimaryOrObject<T, U, C extends TypeConfig> = PreferExplicitConfig<C, Extra
283
300
  } : Primary<U>;
284
301
  export type EntityDTOProp<E, T, C extends TypeConfig = never> = T extends Scalar ? T : T extends {
285
302
  __serialized?: infer U;
286
- } ? U : T extends LoadedReference<infer U> ? EntityDTO<U, C> : T extends Reference<infer U> ? PrimaryOrObject<E, U, C> : T extends ScalarReference<infer U> ? U : T extends LoadedCollection<infer U> ? EntityDTO<U, C>[] : T extends Collection<infer U> ? PrimaryOrObject<E, U, C>[] : T extends readonly (infer U)[] ? (T extends readonly any[] ? T : U[]) : T extends Relation<T> ? EntityDTO<T, C> : T;
303
+ } ? (IsUnknown<U> extends false ? U : T) : T extends LoadedReference<infer U> ? EntityDTO<U, C> : T extends Reference<infer U> ? PrimaryOrObject<E, U, C> : T extends ScalarReference<infer U> ? U : T extends LoadedCollection<infer U> ? EntityDTO<U, C>[] : T extends Collection<infer U> ? PrimaryOrObject<E, U, C>[] : T extends readonly (infer U)[] ? (T extends readonly any[] ? T : U[]) : T extends Relation<T> ? EntityDTO<T, C> : T;
287
304
  type DTOProbablyOptionalProps<T> = NonNullable<NullableKeys<T, undefined>>;
288
305
  type DTOIsOptional<T, K extends keyof T> = T[K] extends LoadedCollection<any> ? false : K extends PrimaryProperty<T> ? false : K extends DTOProbablyOptionalProps<T> ? true : false;
289
306
  type DTORequiredKeys<T, K extends keyof T> = DTOIsOptional<T, K> extends false ? ExcludeHidden<T, K> & CleanKeys<T, K> : never;
@@ -294,8 +311,14 @@ export type EntityDTO<T, C extends TypeConfig = never> = {
294
311
  [K in keyof T as DTOOptionalKeys<T, K>]?: EntityDTOProp<T, T[K], C> | AddOptional<T[K]>;
295
312
  };
296
313
  type TargetKeys<T> = T extends EntityClass<infer P> ? keyof P : keyof T;
297
- type CheckKey<T> = IsUnknown<T> extends false ? TargetKeys<T> : string;
298
- export type CheckCallback<T> = (columns: Record<CheckKey<T>, string>) => string;
314
+ type PropertyName<T> = IsUnknown<T> extends false ? TargetKeys<T> : string;
315
+ type TableName = {
316
+ name: string;
317
+ schema?: string;
318
+ toString: () => string;
319
+ };
320
+ export type IndexCallback<T> = (table: TableName, columns: Record<PropertyName<T>, string>, indexName: string) => string | RawQueryFragment;
321
+ export type CheckCallback<T> = (columns: Record<PropertyName<T>, string>) => string;
299
322
  export type GeneratedColumnCallback<T> = (columns: Record<keyof T, string>) => string;
300
323
  export interface CheckConstraint<T = any> {
301
324
  name?: string;
@@ -332,6 +355,7 @@ export interface EntityProperty<Owner = any, Target = any> {
332
355
  default?: string | number | boolean | null;
333
356
  defaultRaw?: string;
334
357
  formula?: (alias: string) => string;
358
+ filters?: FilterOptions;
335
359
  prefix?: string | boolean;
336
360
  prefixMode?: EmbeddedPrefixMode;
337
361
  embedded?: [EntityKey<Owner>, EntityKey<Owner>];
@@ -348,7 +372,6 @@ export interface EntityProperty<Owner = any, Target = any> {
348
372
  mapToPk?: boolean;
349
373
  persist?: boolean;
350
374
  hydrate?: boolean;
351
- trackChanges?: boolean;
352
375
  hidden?: boolean;
353
376
  enum?: boolean;
354
377
  items?: (number | string)[];
@@ -359,6 +382,7 @@ export interface EntityProperty<Owner = any, Target = any> {
359
382
  setter?: boolean;
360
383
  getter?: boolean;
361
384
  getterName?: keyof Owner;
385
+ accessor?: EntityKey<Owner>;
362
386
  cascade: Cascade[];
363
387
  orphanRemoval?: boolean;
364
388
  onCreate?: (entity: Owner, em: EntityManager) => any;
@@ -391,6 +415,8 @@ export interface EntityProperty<Owner = any, Target = any> {
391
415
  optional?: boolean;
392
416
  ignoreSchemaChanges?: ('type' | 'extra' | 'default')[];
393
417
  deferMode?: DeferMode;
418
+ createForeignKeyConstraint: boolean;
419
+ foreignKeyName?: string;
394
420
  }
395
421
  export declare class EntityMetadata<T = any> {
396
422
  private static counter;
@@ -399,8 +425,9 @@ export declare class EntityMetadata<T = any> {
399
425
  constructor(meta?: Partial<EntityMetadata>);
400
426
  addProperty(prop: Partial<EntityProperty<T>>, sync?: boolean): void;
401
427
  removeProperty(name: string, sync?: boolean): void;
402
- getPrimaryProps(): EntityProperty<T>[];
428
+ getPrimaryProps(flatten?: boolean): EntityProperty<T>[];
403
429
  getPrimaryProp(): EntityProperty<T>;
430
+ createColumnMappingObject(): Dictionary<any>;
404
431
  get tableName(): string;
405
432
  set tableName(name: string);
406
433
  sync(initIndexes?: boolean, config?: Configuration): void;
@@ -419,7 +446,7 @@ export interface EntityMetadata<T = any> {
419
446
  schema?: string;
420
447
  pivotTable?: boolean;
421
448
  virtual?: boolean;
422
- expression?: string | ((em: any, where: FilterQuery<T>, options: FindOptions<T, any, any, any>) => MaybePromise<RawQueryFragment | object | string>);
449
+ expression?: string | ((em: any, where: ObjectQuery<T>, options: FindOptions<T, any, any, any>, stream?: boolean) => MaybePromise<RawQueryFragment | object | string>);
423
450
  discriminatorColumn?: EntityKey<T> | AnyString;
424
451
  discriminatorValue?: number | string;
425
452
  discriminatorMap?: Dictionary<string>;
@@ -452,18 +479,18 @@ export interface EntityMetadata<T = any> {
452
479
  uniqueProps: EntityProperty<T>[];
453
480
  getterProps: EntityProperty<T>[];
454
481
  indexes: {
455
- properties: EntityKey<T> | EntityKey<T>[];
482
+ properties?: EntityKey<T> | EntityKey<T>[];
456
483
  name?: string;
457
484
  type?: string;
458
485
  options?: Dictionary;
459
- expression?: string;
486
+ expression?: string | IndexCallback<T>;
460
487
  }[];
461
488
  uniques: {
462
- properties: EntityKey<T> | EntityKey<T>[];
489
+ properties?: EntityKey<T> | EntityKey<T>[];
463
490
  name?: string;
464
491
  options?: Dictionary;
465
- expression?: string;
466
- deferMode?: DeferMode;
492
+ expression?: string | IndexCallback<T>;
493
+ deferMode?: DeferMode | `${DeferMode}`;
467
494
  }[];
468
495
  checks: CheckConstraint<T>[];
469
496
  repositoryClass?: string;
@@ -482,6 +509,7 @@ export interface EntityMetadata<T = any> {
482
509
  polymorphs?: EntityMetadata[];
483
510
  root: EntityMetadata<T>;
484
511
  definedProperties: Dictionary;
512
+ hasTriggers?: boolean;
485
513
  /** @internal can be used for computed numeric cache keys */
486
514
  readonly _id: number;
487
515
  }
@@ -492,6 +520,7 @@ export interface CreateSchemaOptions {
492
520
  export interface ClearDatabaseOptions {
493
521
  schema?: string;
494
522
  truncate?: boolean;
523
+ clearIdentityMap?: boolean;
495
524
  }
496
525
  export interface EnsureDatabaseOptions extends CreateSchemaOptions, ClearDatabaseOptions {
497
526
  clear?: boolean;
@@ -554,7 +583,9 @@ export interface GenerateOptions {
554
583
  undefinedDefaults?: boolean;
555
584
  bidirectionalRelations?: boolean;
556
585
  identifiedReferences?: boolean;
557
- entitySchema?: boolean;
586
+ entityDefinition?: 'decorators' | 'defineEntity' | 'entitySchema';
587
+ inferEntityType?: boolean;
588
+ enumMode?: 'ts-enum' | 'union-type' | 'dictionary';
558
589
  esmImport?: boolean;
559
590
  scalarTypeInDecorator?: boolean;
560
591
  scalarPropertiesForRelations?: 'always' | 'never' | 'smart';
@@ -682,12 +713,13 @@ export interface MigrationObject {
682
713
  name: string;
683
714
  class: Constructor<Migration>;
684
715
  }
685
- export type FilterDef = {
716
+ export type FilterDef<T extends object = any> = {
686
717
  name: string;
687
- cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<any, any, any, any> | FindOneOptions<any, any, any, any>, entityName?: EntityName<any>) => Dictionary | Promise<Dictionary>);
718
+ cond: Dictionary | ((args: Dictionary, type: 'read' | 'update' | 'delete', em: any, options?: FindOptions<T, any, any, any> | FindOneOptions<T, any, any, any>, entityName?: EntityName<T>) => MaybePromise<Dictionary>);
688
719
  default?: boolean;
689
- entity?: string[];
720
+ entity?: EntityName<T> | EntityName<T>[];
690
721
  args?: boolean;
722
+ strict?: boolean;
691
723
  };
692
724
  export type Populate<T, P extends string = never> = readonly AutoPath<T, P, `${PopulatePath}`>[] | false;
693
725
  export type PopulateOptions<T> = {
@@ -695,6 +727,7 @@ export type PopulateOptions<T> = {
695
727
  strategy?: LoadStrategy;
696
728
  all?: boolean;
697
729
  filter?: boolean;
730
+ joinType?: 'inner join' | 'left join';
698
731
  children?: PopulateOptions<T[keyof T]>[];
699
732
  };
700
733
  type Loadable<T extends object> = Collection<T, any> | Reference<T> | Ref<T> | readonly T[];
@@ -729,7 +762,7 @@ export type MergeSelected<T, U, F extends string> = T extends Loaded<infer TT, i
729
762
  type MergeFields<F1 extends string, F2 extends string, P1, P2> = P1 | P2 extends '*' ? '*' : F1 | F2;
730
763
  type MergeExcludes<F extends string, E extends string> = F extends E ? never : Exclude<E, F>;
731
764
  export type MergeLoaded<T, U, P extends string, F extends string, E extends string, R extends boolean = false> = T extends Loaded<U, infer PP, infer FF, infer EE> ? string extends FF ? Loaded<T, P, F, AnyStringToNever<EE> | E> : string extends P ? Loaded<U, never, F | (FF & string), MergeExcludes<F | (FF & string), EE | E>> : Loaded<U, P | AnyStringToNever<PP>, MergeFields<F, AnyStringToNever<FF>, P, PP>, MergeExcludes<MergeFields<F, AnyStringToNever<FF>, P, PP>, (R extends true ? never : EE) | E>> : Loaded<T, P, F>;
732
- type AddOptional<T> = undefined | null extends T ? null | undefined : null extends T ? null : undefined extends T ? undefined : never;
765
+ export type AddOptional<T> = undefined | null extends T ? null | undefined : null extends T ? null : undefined extends T ? undefined : never;
733
766
  type LoadedProp<T, L extends string = never, F extends string = '*', E extends string = never> = LoadedLoadable<T, Loaded<ExtractType<T>, L, F, E>>;
734
767
  export type AddEager<T> = ExtractEagerProps<T> & string;
735
768
  export type ExpandHint<T, L extends string> = L | AddEager<T>;
@@ -790,11 +823,11 @@ export interface IHydrator {
790
823
  * Hydrates the whole entity. This process handles custom type conversions, creating missing Collection instances,
791
824
  * mapping FKs to entity instances, as well as merging those entities.
792
825
  */
793
- hydrate<T extends object>(entity: T, meta: EntityMetadata<T>, data: EntityData<T>, factory: EntityFactory, type: 'full' | 'reference', newEntity?: boolean, convertCustomTypes?: boolean, schema?: string, parentSchema?: string): void;
826
+ hydrate<T extends object>(entity: T, meta: EntityMetadata<T>, data: EntityData<T>, factory: EntityFactory, type: 'full' | 'reference', newEntity?: boolean, convertCustomTypes?: boolean, schema?: string, parentSchema?: string, normalizeAccessors?: boolean): void;
794
827
  /**
795
828
  * Hydrates primary keys only
796
829
  */
797
- hydrateReference<T extends object>(entity: T, meta: EntityMetadata<T>, data: EntityData<T>, factory: EntityFactory, convertCustomTypes?: boolean, schema?: string, parentSchema?: string): void;
830
+ hydrateReference<T extends object>(entity: T, meta: EntityMetadata<T>, data: EntityData<T>, factory: EntityFactory, convertCustomTypes?: boolean, schema?: string, parentSchema?: string, normalizeAccessors?: boolean): void;
798
831
  isRunning(): boolean;
799
832
  }
800
833
  export interface HydratorConstructor {
@@ -817,4 +850,11 @@ export type MetadataProcessor = (metadata: EntityMetadata[], platform: Platform)
817
850
  export type ContextProvider<T> = MaybePromise<MikroORM> | ((type: T) => MaybePromise<MikroORM | EntityManager | EntityRepository<any> | {
818
851
  getEntityManager(): EntityManager;
819
852
  }>);
853
+ export type MaybeReturnType<T> = T extends (...args: any[]) => infer R ? R : T;
854
+ export interface EntitySchemaWithMeta<TName extends string = string, TTableName extends string = string, TEntity = any, TBase = never, TProperties extends Record<string, any> = Record<string, any>> extends EntitySchema<TEntity, TBase> {
855
+ readonly name: TName;
856
+ readonly properties: TProperties;
857
+ readonly tableName: TTableName;
858
+ }
859
+ export type InferEntity<Schema> = Schema extends EntitySchemaWithMeta<any, any, infer Entity, any, any> ? Entity : Schema extends EntitySchema<infer Entity> ? Entity : Schema extends EntityClass<infer Entity> ? Entity : Schema;
820
860
  export {};
package/typings.js CHANGED
@@ -45,12 +45,29 @@ export class EntityMetadata {
45
45
  this.sync();
46
46
  }
47
47
  }
48
- getPrimaryProps() {
49
- return this.primaryKeys.map(pk => this.properties[pk]);
48
+ getPrimaryProps(flatten = false) {
49
+ const pks = this.primaryKeys.map(pk => this.properties[pk]);
50
+ if (flatten) {
51
+ return pks.flatMap(pk => {
52
+ if ([ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(pk.kind)) {
53
+ return pk.targetMeta.getPrimaryProps(true);
54
+ }
55
+ return [pk];
56
+ });
57
+ }
58
+ return pks;
50
59
  }
51
60
  getPrimaryProp() {
52
61
  return this.properties[this.primaryKeys[0]];
53
62
  }
63
+ createColumnMappingObject() {
64
+ return Object.values(this.properties).reduce((o, prop) => {
65
+ if (prop.fieldNames) {
66
+ o[prop.name] = prop.fieldNames[0];
67
+ }
68
+ return o;
69
+ }, {});
70
+ }
54
71
  get tableName() {
55
72
  return this.collection;
56
73
  }
@@ -70,14 +87,15 @@ export class EntityMetadata {
70
87
  // `prop.userDefined` is either `undefined` or `false`
71
88
  const discriminator = this.root.discriminatorColumn === prop.name && prop.userDefined === false;
72
89
  // even if we don't have a setter, do not ignore value from database!
73
- const onlyGetter = prop.getter && !prop.setter;
90
+ const onlyGetter = prop.getter && !prop.setter && prop.persist === false;
74
91
  return !prop.inherited && prop.hydrate !== false && !discriminator && !prop.embedded && !onlyGetter;
75
92
  });
76
- this.trackingProps = this.hydrateProps
77
- .filter(prop => !prop.getter && !prop.setter && prop.trackChanges !== false)
78
- .filter(prop => ![ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind))
79
- .filter(prop => !prop.serializedPrimaryKey);
80
- this.selfReferencing = this.relations.some(prop => [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type));
93
+ this.trackingProps = this.hydrateProps.filter(prop => {
94
+ return !prop.getter && !prop.setter && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind);
95
+ });
96
+ this.selfReferencing = this.relations.some(prop => {
97
+ return [this.className, this.root.className].includes(prop.targetMeta?.root.className ?? prop.type);
98
+ });
81
99
  this.hasUniqueProps = this.uniques.length + this.uniqueProps.length > 0;
82
100
  this.virtual = !!this.expression;
83
101
  if (config) {
@@ -109,8 +127,7 @@ export class EntityMetadata {
109
127
  this.props.forEach(prop => this.initIndexes(prop));
110
128
  }
111
129
  this.definedProperties = this.trackingProps.reduce((o, prop) => {
112
- const isCollection = [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(prop.kind);
113
- const isReference = [ReferenceKind.ONE_TO_ONE, ReferenceKind.MANY_TO_ONE].includes(prop.kind) && (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
130
+ const isReference = (prop.inversedBy || prop.mappedBy) && !prop.mapToPk;
114
131
  if (isReference) {
115
132
  // eslint-disable-next-line @typescript-eslint/no-this-alias
116
133
  const meta = this;
@@ -123,13 +140,13 @@ export class EntityMetadata {
123
140
  const hydrator = wrapped.hydrator;
124
141
  const entity = Reference.unwrapReference(val ?? wrapped.__data[prop.name]);
125
142
  const old = Reference.unwrapReference(wrapped.__data[prop.name]);
143
+ if (old && old !== entity && prop.kind === ReferenceKind.MANY_TO_ONE && prop.inversedBy && old[prop.inversedBy]) {
144
+ old[prop.inversedBy].removeWithoutPropagation(this);
145
+ }
126
146
  wrapped.__data[prop.name] = Reference.wrapReference(val, prop);
127
147
  // when propagation from inside hydration, we set the FK to the entity data immediately
128
148
  if (val && hydrator.isRunning() && wrapped.__originalEntityData && prop.owner) {
129
- wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(val, prop.targetMeta.primaryKeys, true);
130
- }
131
- else {
132
- wrapped.__touched = !hydrator.isRunning();
149
+ wrapped.__originalEntityData[prop.name] = Utils.getPrimaryKeyValues(val, prop.targetMeta, true);
133
150
  }
134
151
  EntityHelper.propagate(meta, entity, this, prop, Reference.unwrapReference(val), old);
135
152
  },
@@ -137,23 +154,6 @@ export class EntityMetadata {
137
154
  configurable: true,
138
155
  };
139
156
  }
140
- if (prop.inherited || prop.primary || isCollection || prop.persist === false || prop.trackChanges === false || isReference || prop.embedded) {
141
- return o;
142
- }
143
- o[prop.name] = {
144
- get() {
145
- return this.__helper.__data[prop.name];
146
- },
147
- set(val) {
148
- if (typeof val === 'object' && !!val && '__raw' in val) {
149
- val.assign();
150
- }
151
- this.__helper.__data[prop.name] = val;
152
- this.__helper.__touched = !this.__helper.hydrator.isRunning();
153
- },
154
- enumerable: true,
155
- configurable: true,
156
- };
157
157
  return o;
158
158
  }, { __gettersDefined: { value: true, enumerable: false } });
159
159
  }
@@ -34,8 +34,11 @@ export class ChangeSetComputer {
34
34
  this.processPropertyInitializers(entity, prop, type, map);
35
35
  }
36
36
  }
37
- if (type === ChangeSetType.UPDATE && !wrapped.__initialized && !wrapped.isTouched()) {
38
- return null;
37
+ if (type === ChangeSetType.UPDATE && !wrapped.__initialized) {
38
+ const data = this.comparator.prepareEntity(entity);
39
+ if (Utils.equals(data, wrapped.__originalEntityData)) {
40
+ return null;
41
+ }
39
42
  }
40
43
  const changeSet = new ChangeSet(entity, type, this.computePayload(entity), meta);
41
44
  changeSet.originalEntity = wrapped.__originalEntityData;
@@ -141,7 +144,9 @@ export class ChangeSetComputer {
141
144
  if (!target.isDirty() && changeSet.type !== ChangeSetType.CREATE) {
142
145
  return;
143
146
  }
144
- this.collectionUpdates.add(target);
147
+ if (target.isDirty()) {
148
+ this.collectionUpdates.add(target);
149
+ }
145
150
  if (prop.owner && !this.platform.usesPivotTable()) {
146
151
  changeSet.payload[prop.name] = target.getItems(false).map((item) => item.__helper.__identifier ?? item.__helper.getPrimaryKey());
147
152
  }
@@ -5,6 +5,7 @@ import { type EntityValidator } from '../entity/EntityValidator.js';
5
5
  import { type ChangeSet } from './ChangeSet.js';
6
6
  import { type Configuration } from '../utils/Configuration.js';
7
7
  import type { DriverMethodOptions, IDatabaseDriver } from '../drivers/IDatabaseDriver.js';
8
+ import type { EntityManager } from '../EntityManager.js';
8
9
  export declare class ChangeSetPersister {
9
10
  private readonly driver;
10
11
  private readonly metadata;
@@ -12,10 +13,11 @@ export declare class ChangeSetPersister {
12
13
  private readonly factory;
13
14
  private readonly validator;
14
15
  private readonly config;
16
+ private readonly em;
15
17
  private readonly platform;
16
18
  private readonly comparator;
17
19
  private readonly usesReturningStatement;
18
- constructor(driver: IDatabaseDriver, metadata: MetadataStorage, hydrator: IHydrator, factory: EntityFactory, validator: EntityValidator, config: Configuration);
20
+ constructor(driver: IDatabaseDriver, metadata: MetadataStorage, hydrator: IHydrator, factory: EntityFactory, validator: EntityValidator, config: Configuration, em: EntityManager);
19
21
  executeInserts<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
20
22
  executeUpdates<T extends object>(changeSets: ChangeSet<T>[], batched: boolean, options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
21
23
  executeDeletes<T extends object>(changeSets: ChangeSet<T>[], options?: DriverMethodOptions, withSchema?: boolean): Promise<void>;
@@ -23,7 +25,7 @@ export declare class ChangeSetPersister {
23
25
  private processProperties;
24
26
  private persistNewEntity;
25
27
  private persistNewEntities;
26
- private propagateSchemaFromMetadata;
28
+ private prepareOptions;
27
29
  private persistNewEntitiesBatch;
28
30
  private persistManagedEntity;
29
31
  private persistManagedEntities;
@@ -12,16 +12,18 @@ export class ChangeSetPersister {
12
12
  factory;
13
13
  validator;
14
14
  config;
15
+ em;
15
16
  platform;
16
17
  comparator;
17
18
  usesReturningStatement;
18
- constructor(driver, metadata, hydrator, factory, validator, config) {
19
+ constructor(driver, metadata, hydrator, factory, validator, config, em) {
19
20
  this.driver = driver;
20
21
  this.metadata = metadata;
21
22
  this.hydrator = hydrator;
22
23
  this.factory = factory;
23
24
  this.validator = validator;
24
25
  this.config = config;
26
+ this.em = em;
25
27
  this.platform = this.driver.getPlatform();
26
28
  this.comparator = this.config.getComparator(this.metadata);
27
29
  this.usesReturningStatement = this.platform.usesReturningStatement() || this.platform.usesOutputStatement();
@@ -62,7 +64,7 @@ export class ChangeSetPersister {
62
64
  for (let i = 0; i < changeSets.length; i += size) {
63
65
  const chunk = changeSets.slice(i, i + size);
64
66
  const pks = chunk.map(cs => cs.getPrimaryKey());
65
- options = this.propagateSchemaFromMetadata(meta, options);
67
+ options = this.prepareOptions(meta, options);
66
68
  await this.driver.nativeDelete(meta.root.className, { [pk]: { $in: pks } }, options);
67
69
  }
68
70
  }
@@ -90,7 +92,7 @@ export class ChangeSetPersister {
90
92
  }
91
93
  async persistNewEntity(meta, changeSet, options) {
92
94
  const wrapped = helper(changeSet.entity);
93
- options = this.propagateSchemaFromMetadata(meta, options, {
95
+ options = this.prepareOptions(meta, options, {
94
96
  convertCustomTypes: false,
95
97
  });
96
98
  const res = await this.driver.nativeInsertMany(meta.className, [changeSet.payload], options);
@@ -116,15 +118,17 @@ export class ChangeSetPersister {
116
118
  }
117
119
  }
118
120
  }
119
- propagateSchemaFromMetadata(meta, options, additionalOptions) {
121
+ prepareOptions(meta, options, additionalOptions) {
122
+ const loggerContext = Utils.merge({ id: this.em._id }, this.em.getLoggerContext({ disableContextResolution: true }));
120
123
  return {
121
124
  ...options,
122
125
  ...additionalOptions,
123
126
  schema: options?.schema ?? meta.schema,
127
+ loggerContext,
124
128
  };
125
129
  }
126
130
  async persistNewEntitiesBatch(meta, changeSets, options) {
127
- options = this.propagateSchemaFromMetadata(meta, options, {
131
+ options = this.prepareOptions(meta, options, {
128
132
  convertCustomTypes: false,
129
133
  processCollections: false,
130
134
  });
@@ -175,7 +179,7 @@ export class ChangeSetPersister {
175
179
  }
176
180
  async persistManagedEntitiesBatch(meta, changeSets, options) {
177
181
  await this.checkOptimisticLocks(meta, changeSets, options);
178
- options = this.propagateSchemaFromMetadata(meta, options, {
182
+ options = this.prepareOptions(meta, options, {
179
183
  convertCustomTypes: false,
180
184
  processCollections: false,
181
185
  });
@@ -210,7 +214,9 @@ export class ChangeSetPersister {
210
214
  // of using the raw value from db, we convert it back to the db value explicitly
211
215
  value = prop.customType ? prop.customType.convertToDatabaseValue(insertId, this.platform, { mode: 'serialization' }) : value;
212
216
  changeSet.payload[wrapped.__meta.primaryKeys[0]] = value;
213
- wrapped.__identifier?.setValue(value);
217
+ if (wrapped.__identifier && !Array.isArray(wrapped.__identifier)) {
218
+ wrapped.__identifier.setValue(value);
219
+ }
214
220
  }
215
221
  /**
216
222
  * Sets populate flag to new entities so they are serialized like if they were loaded from the db
@@ -233,7 +239,7 @@ export class ChangeSetPersister {
233
239
  }
234
240
  async updateEntity(meta, changeSet, options) {
235
241
  const cond = changeSet.getPrimaryKey(true);
236
- options = this.propagateSchemaFromMetadata(meta, options, {
242
+ options = this.prepareOptions(meta, options, {
237
243
  convertCustomTypes: false,
238
244
  });
239
245
  if (meta.concurrencyCheckKeys.size === 0 && (!meta.versionProperty || changeSet.entity[meta.versionProperty] == null)) {
@@ -260,7 +266,7 @@ export class ChangeSetPersister {
260
266
  return cond;
261
267
  });
262
268
  const primaryKeys = meta.primaryKeys.concat(...meta.concurrencyCheckKeys);
263
- options = this.propagateSchemaFromMetadata(meta, options, {
269
+ options = this.prepareOptions(meta, options, {
264
270
  fields: primaryKeys,
265
271
  });
266
272
  const res = await this.driver.find(meta.root.className, { $or }, options);
@@ -284,11 +290,22 @@ export class ChangeSetPersister {
284
290
  async reloadVersionValues(meta, changeSets, options) {
285
291
  const reloadProps = meta.versionProperty && !this.usesReturningStatement ? [meta.properties[meta.versionProperty]] : [];
286
292
  if (changeSets[0].type === ChangeSetType.CREATE) {
287
- // do not reload things that already had a runtime value
288
- meta.props
289
- .filter(prop => prop.persist !== false && (prop.autoincrement || prop.generated || prop.defaultRaw))
290
- .filter(prop => (changeSets[0].entity[prop.name] == null && prop.defaultRaw !== 'null') || isRaw(changeSets[0].entity[prop.name]))
291
- .forEach(prop => reloadProps.push(prop));
293
+ for (const prop of meta.props) {
294
+ if (prop.persist === false) {
295
+ continue;
296
+ }
297
+ if (isRaw(changeSets[0].entity[prop.name])) {
298
+ reloadProps.push(prop);
299
+ continue;
300
+ }
301
+ // do not reload things that already had a runtime value
302
+ if (changeSets[0].entity[prop.name] != null || prop.defaultRaw === 'null') {
303
+ continue;
304
+ }
305
+ if (prop.autoincrement || prop.generated || prop.defaultRaw) {
306
+ reloadProps.push(prop);
307
+ }
308
+ }
292
309
  }
293
310
  if (changeSets[0].type === ChangeSetType.UPDATE) {
294
311
  const returning = new Set();
@@ -319,12 +336,12 @@ export class ChangeSetPersister {
319
336
  }
320
337
  return val;
321
338
  });
322
- options = this.propagateSchemaFromMetadata(meta, options, {
339
+ options = this.prepareOptions(meta, options, {
323
340
  fields: Utils.unique(reloadProps.map(prop => prop.name)),
324
341
  });
325
342
  const data = await this.driver.find(meta.className, { [pk]: { $in: pks } }, options);
326
343
  const map = new Map();
327
- data.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, true, this.platform, true), item));
344
+ data.forEach(item => map.set(Utils.getCompositeKeyHash(item, meta, false, this.platform, true), item));
328
345
  for (const changeSet of changeSets) {
329
346
  const data = map.get(helper(changeSet.entity).getSerializedPrimaryKey());
330
347
  this.hydrator.hydrate(changeSet.entity, meta, data, this.factory, 'full', false, true);
@@ -338,6 +355,10 @@ export class ChangeSetPersister {
338
355
  changeSet.payload[prop.name] = value.getValue();
339
356
  return;
340
357
  }
358
+ if (Array.isArray(value) && value.every(item => item instanceof EntityIdentifier)) {
359
+ changeSet.payload[prop.name] = value.map(item => item.getValue());
360
+ return;
361
+ }
341
362
  if (prop.kind === ReferenceKind.MANY_TO_MANY && Array.isArray(value)) {
342
363
  changeSet.payload[prop.name] = value.map(val => val instanceof EntityIdentifier ? val.getValue() : val);
343
364
  return;