Skip to content

Entities with Composite Keys behave weirdly when referenced by OneToMany relationships #589

@darkbasic

Description

@darkbasic

Describe the bug
If an Entity containing a OneToMany relationship toward another Entity with composite keys is present in the cache, Mikro-ORM will behave strangely depending on how many times you will flush related entities. The first time you flush (one or more entities) it works, then it fires an update query with a non-existing id (0) which leads to a rollback.
I'm unsure about what exactly is happening because I'm not super familiar with the innings of UnitOfWork, a repro is pending.

Stack trace

[query] insert into "new_user" default values returning "id" [took 1 ms]
[query] commit
[query] begin
[query] insert into "new_user" default values returning "id" [took 1 ms]
[query] commit
[query] begin
[query] insert into "new_chat" ("owner_id", "recipient_id") values (1, 3) [took 3 ms]
[query] commit
[query] begin
[query] insert into "new_chat" ("owner_id", "recipient_id") values (3, 1) [took 1 ms]
[query] update "new_chat" set "owner_id" = 039m [took 2 ms]
[query] rollback
(node:108262) UnhandledPromiseRejectionWarning: error: update "new_chat" set "owner_id" = $1 - insert or update on table "new_chat" violates foreign key constraint "new_chat_owner_id_foreign"
    at Parser.parseErrorMessage (/home/niko/WebstormProjects/beach/server/node_modules/pg-protocol/src/parser.ts:325:11)
    at Parser.handlePacket (/home/niko/WebstormProjects/beach/server/node_modules/pg-protocol/src/parser.ts:154:21)
    at Parser.parse (/home/niko/WebstormProjects/beach/server/node_modules/pg-protocol/src/parser.ts:106:30)
    at Socket.<anonymous> (/home/niko/WebstormProjects/beach/server/node_modules/pg-protocol/src/index.ts:7:48)
    at Socket.emit (events.js:315:20)
    at Socket.EventEmitter.emit (domain.js:485:12)
    at addChunk (_stream_readable.js:297:12)
    at readableAddChunk (_stream_readable.js:273:9)
    at Socket.Readable.push (_stream_readable.js:214:10)
    at TCP.onStreamRead (internal/stream_base_commons.js:186:23)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:108262) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:108262) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

To Reproduce
A PR with a failing test is available: #590

Expected behavior
Should work despite the order and/or what's already loaded into the cache.

Additional context
The same works if I use IDs instead of composite keys.

Versions

Dependency Version
node 13.14.0
typescript 3.9.3
mikro-orm 3.6.14
pg 8.2.1

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