Skip to content

Commit

Permalink
fix(core): fix extra updates caused by bigint type
Browse files Browse the repository at this point in the history
Mapped types have a `ensureComparable` option that allows them to ensure
the mapped value will be comparable, this is used to normalize things like
JSON or bigint shapes.

While the mechanism itself was working, we were calling `registerManaged`
twice, and only the first call did hydration and therefore had correct
values. In some cases, the second call did override the original entity
data back to the numeric value (which might be returned from mysql/sqlite).

This removes the second call, as it was clearly not necessary, this is
already handled from inside  the `factory.create()` with `merge: true`.

Closes #4249
  • Loading branch information
B4nan committed May 9, 2023
1 parent 4ee6319 commit 2acd25e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
5 changes: 0 additions & 5 deletions packages/core/src/EntityManager.ts
Expand Up @@ -193,10 +193,6 @@ export class EntityManager<D extends IDatabaseDriver = IDatabaseDriver> {
convertCustomTypes: true,
}) as Entity;

if (!meta.virtual) {
em.unitOfWork.registerManaged(entity, data, { refresh: options.refresh, loaded: true });
}

ret.push(entity);
}

Expand Down Expand Up @@ -485,7 +481,6 @@ export class EntityManager<D extends IDatabaseDriver = IDatabaseDriver> {
});

if (!meta.virtual) {
em.unitOfWork.registerManaged(entity, data, { refresh: options.refresh, loaded: true });
await em.lockAndPopulate(entityName, entity, where, options);
}

Expand Down
59 changes: 59 additions & 0 deletions tests/features/custom-types/GH4249.test.ts
@@ -0,0 +1,59 @@
import { BigIntType, Entity, ManyToOne, PrimaryKey, wrap } from '@mikro-orm/core';
import { MikroORM } from '@mikro-orm/mysql';
import { mockLogger } from '../../helpers';

@Entity()
class Author {

@PrimaryKey({ type: BigIntType })
id!: string;

}

@Entity()
class Post {

@PrimaryKey()
id!: number;

@ManyToOne({ entity: () => Author })
author: Author;

constructor(author: Author) {
this.author = author;
}

}

let orm: MikroORM;
let postId: number;

beforeAll(async () => {
orm = await MikroORM.init({
dbName: 'mikro_orm_4249',
port: 3308,
entities: [Author, Post],
});
await orm.schema.refreshDatabase();

const em = orm.em.fork();
const author = new Author();
const post = new Post(author);
em.persist(post);
await em.flush();
postId = post.id;
});

afterAll(async () => {
await orm.close(true);
});

test('4249', async () => {
const em = orm.em.fork();
const post = await em.findOneOrFail(Post, postId);
await wrap(post.author).init();

const mock = mockLogger(orm);
await em.flush();
expect(mock.mock.calls).toEqual([]);
});

0 comments on commit 2acd25e

Please sign in to comment.