fixed bug when many to one entity in relation was not updating

This commit is contained in:
Umed Khudoiberdiev 2016-05-11 18:56:47 +05:00
parent a37dac3afc
commit 0e684ce6c9
6 changed files with 81 additions and 22 deletions

View File

@ -1,7 +1,7 @@
{
"name": "typeorm",
"private": true,
"version": "0.0.2-alpha.15",
"version": "0.0.2-alpha.16",
"description": "Data-mapper ORM for Typescript",
"license": "Apache-2.0",
"readmeFilename": "README.md",

View File

@ -39,6 +39,9 @@ createConnection(options).then(connection => {
author.name = "Umed";
post.author = author;
let author2 = new Author();
author2.name = "Bakhrom";
postRepository
.persist(post)
.then(post => {
@ -56,9 +59,7 @@ createConnection(options).then(connection => {
let category3 = new Category();
category3.name = "category #3";
post.categories.push(category3);
let author2 = new Author();
author2.name = "Bakhrom";
post.author = author2;
return postRepository.persist(post);
@ -71,6 +72,51 @@ createConnection(options).then(connection => {
.where("post.id=:id", { id: post.id })
.getSingleResult();
})
.then(loadedPost => {
console.log(loadedPost);
console.log("Lets update a post - return old author back:");
console.log("updating with: ", author);
loadedPost.title = "Umed's post";
loadedPost.author = author;
return postRepository.persist(loadedPost);
})
.then(updatedPost => {
return postRepository
.createQueryBuilder("post")
.leftJoinAndSelect("post.author", "author")
.leftJoinAndSelect("post.categories", "categories")
.where("post.id=:id", { id: post.id })
.getSingleResult();
})
.then(loadedPost => {
console.log(loadedPost);
console.log("Now lets remove post's author:");
post.author = null;
return postRepository.persist(post);
})
.then(updatedPost => {
return postRepository
.createQueryBuilder("post")
.leftJoinAndSelect("post.author", "author")
.leftJoinAndSelect("post.categories", "categories")
.where("post.id=:id", { id: post.id })
.getSingleResult();
})
.then(loadedPost => {
console.log(loadedPost);
console.log("Finally bakhrom's post:");
post.author = author2;
return postRepository.persist(post);
})
.then(updatedPost => {
return postRepository
.createQueryBuilder("post")
.leftJoinAndSelect("post.author", "author")
.leftJoinAndSelect("post.categories", "categories")
.where("post.id=:id", { id: post.id })
.getSingleResult();
})
.then(loadedPost => {
console.log(loadedPost);
})

View File

@ -24,7 +24,7 @@ export class Post {
@JoinTable()
categories: Category[];
@ManyToOne(type => Author, { cascadeAll: true })
author: Author;
@ManyToOne(type => Author, { cascadeInsert: true })
author: Author|null;
}

View File

@ -143,14 +143,15 @@ export class EntityPersistOperationBuilder {
if (!dbEntity)
return operations;
const diff = this.diffColumns(metadata, newEntity, dbEntity);
if (diff.length && fromRelation && !this.checkCascadesAllowed("update", metadata, fromRelation)) {
const diffColumns = this.diffColumns(metadata, newEntity, dbEntity);
const diffRelations = this.diffRelations(metadata, newEntity, dbEntity);
if (diffColumns.length && fromRelation && !this.checkCascadesAllowed("update", metadata, fromRelation)) {
return operations;
} else if (diff.length) {
} else if (diffColumns.length || diffRelations.length) {
const entityId = newEntity[metadata.primaryColumn.name];
if (entityId)
operations.push(new UpdateOperation(newEntity, entityId, diff));
operations.push(new UpdateOperation(newEntity, entityId, diffColumns, diffRelations));
}
metadata.relations.forEach(relation => {
@ -167,13 +168,11 @@ export class EntityPersistOperationBuilder {
const subDbEntity = dbValue.find((subDbEntity: any) => {
return subDbEntity[relationIdColumnName] === subEntity[relationIdColumnName];
});
const relationOperations = this.findCascadeUpdateEntities(relMetadata, subDbEntity, subEntity, relation, operations);
operations.push(...relationOperations);
this.findCascadeUpdateEntities(relMetadata, subDbEntity, subEntity, relation, operations);
});
} else {
const relationOperations = this.findCascadeUpdateEntities(relMetadata, dbValue, value, relation, operations);
operations.push(...relationOperations);
this.findCascadeUpdateEntities(relMetadata, dbValue, value, relation, operations);
}
});
@ -344,7 +343,13 @@ export class EntityPersistOperationBuilder {
private diffColumns(metadata: EntityMetadata, newEntity: any, dbEntity: any) {
return metadata.columns
.filter(column => !column.isVirtual && !column.isUpdateDate && !column.isVersion && !column.isCreateDate)
.filter(column => newEntity[column.propertyName] !== dbEntity[column.propertyName]);
.filter(column => newEntity[column.propertyName] !== dbEntity[column.name]);
}
private diffRelations(metadata: EntityMetadata, newEntity: any, dbEntity: any) {
return metadata.relations
.filter(relation => relation.isManyToOne || (relation.isOneToOne && relation.isOwning))
.filter(relation => newEntity[relation.propertyName] !== dbEntity[relation.name]);
}
private findEntityWithId(entityWithIds: EntityWithId[], entityClass: Function, id: any) {

View File

@ -304,14 +304,20 @@ export class PersistOperationExecutor {
private update(updateOperation: UpdateOperation) {
const entity = updateOperation.entity;
const metadata = this.entityMetadatas.findByTarget(entity.constructor);
const values: any = updateOperation.columns.reduce((object, column) => {
const value = this.driver.preparePersistentValue(entity[column.propertyName], column);
(<any> object)[column.name] = value;
return object;
}, {});
// todo: what if number of updated columns = 0 ? + probably no need to update updated date and version columns
const values: { [key: string]: any } = {};
updateOperation.columns.forEach(column => {
values[column.name] = this.driver.preparePersistentValue(entity[column.propertyName], column);
});
updateOperation.relations.forEach(relation => {
values[relation.name] = entity[relation.propertyName] ? entity[relation.propertyName][relation.inverseEntityMetadata.primaryColumn.propertyName] : null;
});
// if number of updated columns = 0 no need to update updated date and version columns
if (Object.keys(values).length === 0)
return Promise.resolve();
if (metadata.updateDateColumn)
values[metadata.updateDateColumn.name] = this.driver.preparePersistentValue(new Date(), metadata.updateDateColumn);

View File

@ -1,4 +1,5 @@
import {ColumnMetadata} from "../../metadata/ColumnMetadata";
import {RelationMetadata} from "../../metadata/RelationMetadata";
/**
* @internal
@ -7,6 +8,7 @@ export class UpdateOperation {
constructor(public entity: any,
public entityId: any,
public columns: ColumnMetadata[],
public relations: RelationMetadata[],
public date = new Date()) {
}
}