Skip to content

Commit

Permalink
fix(core): do not merge entity instances in em.create()
Browse files Browse the repository at this point in the history
Previously `em.create(Book, { tags: [t1, t2] })`, where t1 and t2 are entity instances, did automatically merge those in case
they had PK set. This obviously don't work for composite keys, where we always know the PK.

With this change, only PKs will be converted to references and merged, rest will be considered as new entities.

cherry pick of fe204c6
  • Loading branch information
B4nan committed Jun 5, 2020
1 parent a55ea22 commit 30010f8
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 12 deletions.
21 changes: 12 additions & 9 deletions lib/hydration/ObjectHydrator.ts
@@ -1,6 +1,6 @@
import { AnyEntity, EntityData, EntityProperty, Primary } from '../typings';
import { Hydrator } from './Hydrator';
import { Collection, EntityAssigner, ReferenceType, wrap } from '../entity';
import { Collection, EntityAssigner, ReferenceType } from '../entity';
import { Utils } from '../utils';

export class ObjectHydrator extends Hydrator {
Expand Down Expand Up @@ -75,18 +75,21 @@ export class ObjectHydrator extends Hydrator {
}
}

private createCollectionItem<T extends AnyEntity<T>>(prop: EntityProperty, value: Primary<T> | EntityData<T>): T {
if (Utils.isPrimaryKey(value)) {
return this.factory.createReference(prop.type, value);
}
private createCollectionItem<T extends AnyEntity<T>>(prop: EntityProperty, value: Primary<T> | EntityData<T> | T): T {
const meta = this.em.getMetadata().get(prop.type);

if (Utils.isPrimaryKey(value, meta.compositePK)) {
const ref = this.factory.createReference<T>(prop.type, value);
this.em.merge(ref);

const child = this.factory.create(prop.type, value as EntityData<T>);
return ref;
}

if (wrap(child).__primaryKey) {
this.em.merge(child);
if (Utils.isEntity<T>(value)) {
return value;
}

return child;
return this.factory.create(prop.type, value as EntityData<T>);
}

}
2 changes: 1 addition & 1 deletion lib/typings.ts
Expand Up @@ -94,7 +94,7 @@ export type MongoEntity<T extends { _id: IPrimaryKey; id: string }> = AnyEntity<
export type EntityClass<T extends AnyEntity<T>> = Function & { prototype: T };
export type EntityClassGroup<T extends AnyEntity<T>> = { entity: EntityClass<T>; schema: EntityMetadata<T> | EntitySchema<T> };
export type EntityName<T extends AnyEntity<T>> = string | EntityClass<T>;
export type EntityData<T extends AnyEntity<T>> = { [K in keyof T]?: T[K] | Primary<T[K]> | CollectionItem<T[K]>[] } & Dictionary;
export type EntityData<T extends AnyEntity<T>> = { [K in keyof T]?: T[K] | Primary<T[K]> | EntityData<T[K]> | CollectionItem<T[K]>[] } & Dictionary;

export interface EntityProperty<T extends AnyEntity<T> = any> {
name: string & keyof T;
Expand Down
4 changes: 2 additions & 2 deletions tests/EntityManager.mongo.test.ts
Expand Up @@ -789,10 +789,10 @@ describe('EntityManagerMongo', () => {
const cachedAuthor = orm.em.merge(Author, cache);
expect(cachedAuthor).toBe(cachedAuthor.favouriteBook.author);
expect(Object.keys(orm.em.getUnitOfWork().getIdentityMap())).toEqual([
'BookTag-' + tag1.id,
'BookTag-' + tag3.id,
'Author-' + author.id,
'Book-' + book1.id,
'BookTag-' + tag1.id,
'BookTag-' + tag3.id,
]);
expect(author).not.toBe(cachedAuthor);
expect(author.id).toBe(cachedAuthor.id);
Expand Down

0 comments on commit 30010f8

Please sign in to comment.