Skip to content

Commit

Permalink
fix(core): fix updating complex composite key entities via UoW (#4739)
Browse files Browse the repository at this point in the history
Closes #4720
  • Loading branch information
B4nan committed Sep 24, 2023
1 parent ce574a4 commit 898dcda
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/core/src/unit-of-work/ChangeSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ export class ChangeSet<T> {

if (object && this.primaryKey != null) {
const pks = this.meta.compositePK && Utils.isPlainObject(this.primaryKey) ? Object.values(this.primaryKey) : Utils.asArray(this.primaryKey);
const pkProps = this.meta.getPrimaryProps();
const ret = this.meta.primaryKeys.reduce((o, pk, idx) => {
const pkProp = pkProps[idx];

if (Utils.isPlainObject(pks[idx]) && pkProp.targetMeta) {
o[pk] = Utils.getOrderedPrimaryKeys(pks[idx], pkProp.targetMeta) as any;
return o;
}

o[pk] = pks[idx] as any;
return o;
}, {} as T);
Expand Down
109 changes: 109 additions & 0 deletions tests/issues/GH4720.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
Collection,
Entity,
LoadStrategy,
ManyToOne,
OneToMany,
PrimaryKey,
PrimaryKeyProp,
PrimaryKeyType,
Property,
Unique,
} from '@mikro-orm/core';
import { MikroORM } from '@mikro-orm/postgresql';

@Entity()
class Parent {

@PrimaryKey()
id!: number;

@Property()
@Unique()
uniqueProp!: string;

@OneToMany({ entity: () => Child, mappedBy: 'parent' })
children: Collection<Child> = new Collection<Child>(this);

@Property()
data!: string;

}
@Entity()
class ChildType {

[PrimaryKeyProp]?: 'foo' | 'boo';
[PrimaryKeyType]?: [string, string];

@PrimaryKey()
foo!: string;

@PrimaryKey()
boo!: string;

@Property()
data!: string;

}

@Entity()
class Child {

[PrimaryKeyProp]?: 'parent' | 'type';
[PrimaryKeyType]?: [number, [string, string]];

@ManyToOne({ entity: () => Parent, primary: true })
parent!: Parent;

@ManyToOne({ entity: () => ChildType, primary: true })
type!: ChildType;

@Property()
data!: string;

}

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
entities: [Parent],
dbName: '4720',
loadStrategy: LoadStrategy.JOINED,
});
await orm.schema.refreshDatabase();
});

afterAll(() => orm.close(true));

test('GH 4720', async () => {
const parent = await orm.em.insert(Parent, {
uniqueProp: 'aaa',
data: '123',
});
await orm.em.insertMany(ChildType, [
{ foo: 'f1', boo: 'b1', data: '456' },
{ foo: 'f2', boo: 'b2', data: '789' },
]);
await orm.em.insertMany(Child, [
{ parent, type: ['f1', 'b1'], data: '111' },
{ parent, type: ['f2', 'b2'], data: '222' },
]);

const p = await orm.em.findOneOrFail(Parent, {
uniqueProp: 'aaa',
});

p.data = 'pppppppppp';
await orm.em.flush();

const sameParent = await orm.em.findOneOrFail(
Parent,
{ uniqueProp: 'aaa' },
{ populate: ['children', 'children.type'] },
);

sameParent.children[0].data = 'eeeeeeeeeee';
sameParent.children[1].data = 'wwwwwwwwwww';
await orm.em.flush();
});

0 comments on commit 898dcda

Please sign in to comment.