fixed bug when same object instance was saved to db twice

This commit is contained in:
Umed Khudoiberdiev 2016-03-22 00:28:32 +05:00
parent 3b43d2a00d
commit 72356c8e6c
3 changed files with 24 additions and 23 deletions

View File

@ -106,9 +106,8 @@ export class EntityPersistOperationBuilder {
private findCascadeInsertedEntities(newEntity: any,
dbEntities: EntityWithId[],
fromRelation: RelationMetadata): InsertOperation[] {
let operations: InsertOperation[] = [];
fromRelation: RelationMetadata,
operations: InsertOperation[] = []): InsertOperation[] {
const metadata = this.connection.getMetadata(newEntity.constructor);
const isObjectNew = !this.findEntityWithId(dbEntities, metadata.target, newEntity[metadata.primaryColumn.name]);
@ -116,7 +115,7 @@ export class EntityPersistOperationBuilder {
if (isObjectNew && !this.checkCascadesAllowed("insert", metadata, fromRelation)) {
return operations; // looks like object is new here, but cascades are not allowed - then we should stop iteration
} else if (isObjectNew) { // object is new and cascades are allow here
} else if (isObjectNew && !operations.find(o => o.entity === newEntity)) { // object is new and cascades are allow here
operations.push(new InsertOperation(newEntity));
}
@ -126,12 +125,10 @@ export class EntityPersistOperationBuilder {
const value = newEntity[relation.propertyName];
if (value instanceof Array) {
value.forEach((subEntity: any) => {
const subInserted = this.findCascadeInsertedEntities(subEntity, dbEntities, relation);
operations = operations.concat(subInserted);
this.findCascadeInsertedEntities(subEntity, dbEntities, relation, operations);
});
} else {
const subInserted = this.findCascadeInsertedEntities(value, dbEntities, relation);
operations = operations.concat(subInserted);
this.findCascadeInsertedEntities(value, dbEntities, relation, operations);
}
});

View File

@ -29,6 +29,7 @@ export class PersistOperationExecutor {
*/
executePersistOperation(persistOperation: PersistOperation) {
const broadcaster = new OrmBroadcaster(this.connection);
persistOperation.log();
return Promise.resolve()
.then(() => this.broadcastBeforeEvents(broadcaster, persistOperation))

View File

@ -218,27 +218,30 @@ export class Repository<Entity> {
/**
* Extracts unique objects from given entity and all its downside relations.
*/
private extractObjectsById(entity: any, metadata: EntityMetadata): EntityWithId[] {
private extractObjectsById(entity: any, metadata: EntityMetadata, entityWithIds: EntityWithId[] = []): EntityWithId[] {
if (!entity)
return [];
return entityWithIds;
return metadata.relations
metadata.relations
.filter(relation => !!entity[relation.propertyName])
.map(relation => {
.forEach(relation => {
const relMetadata = relation.relatedEntityMetadata;
if (!(entity[relation.propertyName] instanceof Array))
return this.extractObjectsById(entity[relation.propertyName], relMetadata);
return entity[relation.propertyName]
.map((subEntity: any) => this.extractObjectsById(subEntity, relMetadata))
.reduce((col1: any[], col2: any[]) => col1.concat(col2), []); // flatten
})
.reduce((col1: any[], col2: any[]) => col1.concat(col2), []) // flatten
.concat([{
const value = entity[relation.propertyName];
if (value instanceof Array) {
value.forEach((subEntity: any) => this.extractObjectsById(subEntity, relMetadata, entityWithIds));
} else {
this.extractObjectsById(value, relMetadata, entityWithIds);
}
});
if (!entityWithIds.find(entityWithId => entityWithId.entity === entity)) {
entityWithIds.push({
id: entity[metadata.primaryColumn.name],
entity: entity
}])
.filter((entity: any, index: number, allEntities: any[]) => allEntities.indexOf(entity) === index); // unique
});
}
return entityWithIds;
}
}