Skip to content

UoW Changesets from FlushEventArgs contain incorrect changes #864

@followben

Description

@followben

Describe the bug
On receiving an afterFlush() callback to our EntitySubscriber and accessing args.uow.getChangeSets(), we see UPDATE changes for entities we've populated during a find() but never mutated.

This occurs because registerManaged() in the UoW sometimes incorrectly receives WrappedEntity instances, so updates __originalEntityData with a reference, e.g. {id: '12'}. The changeset computer later diffs that with the full entity representation, sees it as a change and adds an UPDATE changeset to the persistStack.

On Martin's suggestion, I added console.log(entity, new Error().stack) to registerManaged() at L72, just after it assigns the original entity data. Our callsite is:

await orm.em.getRepository(Credential).findOne(
	{
		// ... some where clause
	},
	['user.organisation']
);

Here's the output:

Stack trace

User {id: '1', __helper: WrappedEntity} Error: 
    at UnitOfWork.registerManaged (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/unit-of-work/UnitOfWork.js:60:33)
    at EntityFactory.create (/Users/bstovold/Documents//backend/node_modules/@mikro-orm/core/entity/EntityFactory.js:35:29)
    at EntityFactory.createReference (/Users/bstovold/Documents/node_modules/@mikro-orm/core/entity/EntityFactory.js:57:21)
    at ObjectHydrator.hydrateToOne (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/hydration/ObjectHydrator.js:64:82)
    at ObjectHydrator.hydrateProperty (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/hydration/ObjectHydrator.js:13:18)
    at ObjectHydrator.hydrate (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/hydration/Hydrator.js:16:18)
    at EntityFactory.hydrate (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/entity/EntityFactory.js:85:27)
    at EntityFactory.create (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/entity/EntityFactory.js:33:14)
    at SqlEntityManager.findOne (/Users/bstovold/Documents/backend/node_modules/@mikro-orm/core/EntityManager.js:166:42)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at Function.Credential.fromApiKey (/Users/bstovold/Documents/backend/packages/database-entities/src/entities/credential.ts:116:22)

To Reproduce
I have not been able to reproduce this in a standalone test harness.

Expected behavior
Relations populated during find() but not altered should not end up in changesets.

Additional context
I'm upgrading from 4.0.0-rc2 to 4.6.0. This only occurs on 4.0.3 and above. On 4.0.0-rc3 to 4.0.2 inclusive I see a different problem with metadata references being undefined, which may or may still be there once this issue is resolved. The last functional release for us appears to be 4.0.0-rc2.

Versions

Dependency Version
node 12.x
typescript 3.9.3
mikro-orm 4.0.6
pg 3.8.3

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions