-
-
Notifications
You must be signed in to change notification settings - Fork 611
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Describe the bug
Issue with custom type for primary key conversion with LoadStrategy.JOINED.
Stack trace
[query] select `e0`.`id`, `e0`.`author_id`, `a1`.`id` as `a1__id` from `book` as `e0` left join `author` as `a1` on `e0`.`author_id` = `a1`.`id` where `e0`.`id` = X'671b206cf43b45dbaf5c32c7eb5269bc' [took 2 ms]
JIT runtime error: Stringified UUID is invalid
function(entity, data, factory, newEntity, convertCustomTypes) {
if (typeof data.id !== 'undefined') {
if (convertCustomTypes) {
const value = convertToJSValue_id(data.id);
data.id = convertToDatabaseValue_id(value);
entity.id = value;
} else {
entity.id = data.id;
}
}
if (data.author === null) {
entity.author = null;
} else if (typeof data.author !== 'undefined') {
if (isPrimaryKey(data.author, true)) {
entity.author = factory.createReference('Author', data.author, { merge: true });
} else if (data.author && typeof data.author === 'object') {
entity.author = factory.create('Author', data.author, { initialized: true, merge: true, newEntity });
}
}
if (data.author != null && convertCustomTypes) {
const value = convertToJSValue_author(data.author);
data.author = convertToDatabaseValue_author(value);
}
}
[Nest] 862668 - 12/24/2020, 4:15:15 PM [ExceptionsHandler] Stringified UUID is invalid +198036ms
TypeError: Stringified UUID is invalid
at Object.stringify (/home/virchenko/Projects/test/test-project/node_modules/uuid/dist/stringify.js:32:11)
at UuidBinaryType.convertToJSValue (/home/virchenko/Projects/test/test-project/dist/src/uuid-binary-type.js:11:23)
at /home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/hydration/ObjectHydrator.js:109:91
at eval (eval at createFunction (/home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/utils/Utils.js:580:52), <anonymous>:21:19)
at Function.callCompiledFunction (/home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/utils/Utils.js:591:20)
at ObjectHydrator.hydrate (/home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/hydration/ObjectHydrator.js:23:23)
at EntityFactory.hydrate (/home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/entity/EntityFactory.js:81:27)
at EntityFactory.create (/home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/entity/EntityFactory.js:35:14)
at SqlEntityManager.findOne (/home/virchenko/Projects/test/test-project/node_modules/@mikro-orm/core/EntityManager.js:197:42)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
To Reproduce
Steps to reproduce the behavior:
- Create some entities, for example:
import { Entity, ManyToOne, PrimaryKey} from '@mikro-orm/core';
import { Author } from './author';
import { v4 } from 'uuid';
import { UuidBinaryType } from '../uuid-binary-type';
@Entity({
tableName: 'book',
})
export class Book {
@PrimaryKey({ type: UuidBinaryType })
readonly id = v4();
@ManyToOne()
author!: Author;
}
and
import { Entity, PrimaryKey } from '@mikro-orm/core';
import { v4 } from 'uuid';
import { UuidBinaryType } from '../uuid-binary-type';
@Entity({
tableName: 'author',
})
export class Author {
@PrimaryKey({ type: UuidBinaryType })
readonly id = v4();
}
- Create custom type:
import { Type } from '@mikro-orm/core';
import { parse, stringify } from 'uuid';
export class UuidBinaryType extends Type<string, Buffer> {
convertToDatabaseValue(value: string): Buffer {
return Buffer.from(parse(value));
}
convertToJSValue(value: Buffer): string {
return stringify(value);
}
getColumnType(): string {
return 'binary(16)';
}
}
- Set loadStrategy by default in MikroOrmModule:
{
...
loadStrategy: LoadStrategy.JOINED,
}
- Persist some entities:
const author = new Author();
const book = new Book();
book.author = author;
this.em.persist(author);
this.em.persist(book);
await this.em.flush();
- Load entity with the populated relation:
await this.em.getRepository(Book).findOne(id, ['author']);
Expected behavior
Relation is populated correctly.
Additional context
It works well without JOINED strategy with no changes.
Seems like the whole Ref is pushed inside UuidBinaryType, and even if change it to something like this:
import { Type } from '@mikro-orm/core';
import { parse, stringify } from 'uuid';
export class UuidBinaryType extends Type<string, Buffer> {
convertToDatabaseValue(value: string): Buffer {
return Buffer.from(parse(value));
}
convertToJSValue(value: any): string {
if (value.hasOwnProperty('id')) {
return Buffer.isBuffer(value.id) ? stringify(value.id) : value.id;
}
return stringify(value);
}
getColumnType(): string {
return 'binary(16)';
}
}
it starts working, but gives unconverted result:
Author { id: <Buffer 96 dc 32 86 75 40 42 a4 91 1c 09 5f 32 35 fe b3> }
Versions
| Dependency | Version |
| uuid | 8.3.2 |
| node | v12.20.0 |
| typescript | 4.0.5 |
| mikro-orm | 4.3.4 |
| mysql | 8.0.22 |
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working