perf: improve save performance during entities update

Co-authored-by: Lukasz Otczyk <lukasz.otczyk@nexontis.com>
This commit is contained in:
Lukasz Otczyk 2025-05-11 21:37:46 +02:00 committed by GitHub
parent 2168441e6c
commit 15de733e28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3,6 +3,7 @@ import { ObjectLiteral } from "../common/ObjectLiteral"
import { QueryRunner } from "../query-runner/QueryRunner"
import { FindManyOptions } from "../find-options/FindManyOptions"
import { MongoRepository } from "../repository/MongoRepository"
import { OrmUtils } from "../util/OrmUtils"
/**
* Loads database entities for all operate subjects which do not have database entity set.
@ -123,20 +124,17 @@ export class SubjectDatabaseEntityLoader {
.getMany()
}
// now when we have entities we need to find subject of each entity
// and insert that entity into database entity of the found subjects
// Now when we have entities we need to find subject of each entity
// and insert that entity into database entity of the found subjects.
// A single entity can be applied to many subjects as there might be duplicates.
// This will likely result in the same row being updated multiple times during a transaction.
entities.forEach((entity) => {
const subjects = this.findByPersistEntityLike(
subjectGroup.target,
entity,
)
subjects.forEach((subject) => {
subject.databaseEntity = entity
if (!subject.identifier)
subject.identifier =
subject.metadata.hasAllPrimaryKeys(entity)
? subject.metadata.getEntityIdMap(entity)
: undefined
const entityId =
allSubjects[0].metadata.getEntityIdMap(entity)
allSubjects.forEach((subject) => {
if (subject.databaseEntity) return
if (OrmUtils.compareIds(subject.identifier, entityId))
subject.databaseEntity = entity
})
})
@ -154,31 +152,6 @@ export class SubjectDatabaseEntityLoader {
// Protected Methods
// ---------------------------------------------------------------------
/**
* Finds subjects where entity like given subject's entity.
* Comparison made by entity id.
* Multiple subjects may be returned if duplicates are present in the subject array.
* This will likely result in the same row being updated multiple times during a transaction.
*/
protected findByPersistEntityLike(
entityTarget: Function | string,
entity: ObjectLiteral,
): Subject[] {
return this.subjects.filter((subject) => {
if (!subject.entity) return false
if (subject.entity === entity) return true
return (
subject.metadata.target === entityTarget &&
subject.metadata.compareEntities(
subject.entityWithFulfilledIds!,
entity,
)
)
})
}
/**
* Groups given Subject objects into groups separated by entity targets.
*/