Skip to content

Commit

Permalink
fix(UnitOfWork): throw error on missing pk value and add config to co…
Browse files Browse the repository at this point in the history
…mmit

BREAKING CHANGE: This change will start throwing different errors. If you matched on the error message before you'll have to change that. Check the diff for details. Also, entities used to have null properties if no AI PK was found. This has been fixed. If you checked for them, please upodate your code.
  • Loading branch information
RWOverdijk committed Aug 2, 2018
1 parent 4524f6b commit cbf5f6e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
32 changes: 22 additions & 10 deletions src/Scope.ts
Expand Up @@ -134,11 +134,20 @@ export class Scope {
let refreshes = [];
let hydrator = new Hydrator(this);

if (!Array.isArray(entity) || !entity.length) {
return Promise.resolve(null);
}

entity.forEach(toRefresh => {
let entityCtor = this.resolveEntityReference(toRefresh);
let primaryKeyName = Mapping.forEntity(entityCtor).getPrimaryKey();
let primaryKey = toRefresh[primaryKeyName];
let refresh = this.getRepository(entityCtor).getQueryBuilder()
const entityCtor = this.resolveEntityReference(toRefresh);
const primaryKeyName = Mapping.forEntity(entityCtor).getPrimaryKey();
const primaryKey = toRefresh[primaryKeyName];

if (!primaryKey) {
return refreshes.push(Promise.reject(new Error('Cannot refresh entity without a PK value.')));
}

const refresh = this.getRepository(entityCtor).getQueryBuilder()
.where({[primaryKeyName]: primaryKey})
.limit(1)
.getQuery()
Expand Down Expand Up @@ -268,13 +277,16 @@ export class Scope {
* This means calculating changes to make, as well as the order to do so.
* One of the things involved in this is making the distinction between stores.
*
* @param {boolean} skipClean
* @param {boolean} skipLifecyclehooks
*
* @return {Promise}
* @param {boolean} skipClean
* @param {boolean} skipLifecycleHooks
* @param {refreshCreated: boolean, refreshUpdated: boolean} config
*/
public flush(skipClean: boolean = false, skipLifecyclehooks: boolean = false): Promise<any> {
return this.unitOfWork.commit(skipClean, skipLifecyclehooks);
public flush(
skipClean: boolean = false,
skipLifecycleHooks: boolean = false,
config: {refreshCreated?: boolean, refreshUpdated?: boolean} = {refreshCreated: null, refreshUpdated: null}
): Promise<any> {
return this.unitOfWork.commit(skipClean, skipLifecycleHooks, config);
}

/**
Expand Down
25 changes: 20 additions & 5 deletions src/UnitOfWork.ts
Expand Up @@ -556,21 +556,32 @@ export class UnitOfWork {
/**
* Commit the current state.
*
* @param {boolean} skipClean
* @param {boolean} skipLifecycleHooks
* @param {boolean} skipClean
* @param {boolean} skipLifecycleHooks
* @param {refreshCreated: boolean, refreshUpdated: boolean} config
*
* @returns {Promise<UnitOfWork>}
*/
public commit(skipClean: boolean = false, skipLifecycleHooks: boolean = false): Promise<any> {
public commit(
skipClean: boolean = false,
skipLifecycleHooks: boolean = false,
config: {refreshCreated?: boolean, refreshUpdated?: boolean} = {refreshCreated: null, refreshUpdated: null}
): Promise<any> {
this.prepareCascades();

const defaultConfig = this.entityManager.getConfig();
const refreshCreated = defaultConfig.fetch('entityManager.refreshCreated');
const refreshUpdated = defaultConfig.fetch('entityManager.refreshUpdated');
const shouldRefreshUpdate = typeof config.refreshUpdated === 'boolean' ? config.refreshUpdated : refreshUpdated;
const shouldRefreshCreate = typeof config.refreshCreated === 'boolean' ? config.refreshCreated : refreshCreated;

return this.insertNew(skipLifecycleHooks)
.then(() => this.updateDirty(skipLifecycleHooks))
.then(() => this.deleteDeleted(skipLifecycleHooks))
.then(() => this.updateRelationships())
.then(() => this.commitOrRollback(true))
.then(() => this.entityManager.getConfig().fetch('entityManager.refreshUpdated') && this.refreshDirty())
.then(() => this.entityManager.getConfig().fetch('entityManager.refreshCreated') && this.refreshNew())
.then(() => shouldRefreshUpdate && this.refreshDirty())
.then(() => shouldRefreshCreate && this.refreshNew())
.then(() => !skipClean && this.cleanObjectsAndTransactions())
.then(() => !skipClean && this.processAfterCommit())
.then(() => !skipClean && this.cleanAfterCommit())
Expand Down Expand Up @@ -818,6 +829,10 @@ export class UnitOfWork {
const executeInsertion = () => {
return queryBuilder.insert(target, primaryKey).getQuery().execute()
.then(result => {
if (!primaryKey) {
return;
}

if (target.isEntityProxy) {
target[primaryKey] = {_skipDirty: result[0]};

Expand Down

0 comments on commit cbf5f6e

Please sign in to comment.