typeorm create() method is extremely slow

10k views Asked by At

I was using

queryRunner.manager.create(…) 

to create the entity before calling the save method.

I noticed that for a specific customer with lots of data the create step took > 2 sec. when I replaced the create with just creating the new entity myself

const myEntity = new MyEntity();

it made the saving much much faster.

any reason for the create to take so much time? could it be related to the relations this entity has?

2

There are 2 answers

0
Tamar Duchovny On BEST ANSWER

The issue was due to the way TypeOrm transforms relations instances in the create() method, it seems that typeOrm is running transform, on each given entity in the create and each of the related entities to it (if you send the full relation instance with its relations in the create() method).

Before any fixes, my call to create() looked like this:

const transaction = queryRunner.manager.create(Transaction, {
      seller: sellerInstance,
      buyer: buyerInstance
    });

Solution 1: Sending ids only — if you still want to use create() make sure you don’t send the full relation instance in the create fields, send only the ids. (This field is the only thing you really need as this is the real reference in the table).

const transaction = queryRunner.manager.create(Transaction, {
  seller: { id: sellerInstance.id },
  buyer: { id: buyerInstance.id },
});

Solution 2: You can always use new()

const transaction = new Transaction();
transaction.seller = sellerInstance;
transaction.buyer = buyerInstance;

checkout my blog post for additional details on this issue:

https://tamar-duchovny.medium.com/two-lines-change-turned-a-6-sec-request-to-300ms-cf0f13c00a75

1
kampfmoehre On

I also had a problem with repository.create() when using references to other entitites. I had a complex operation where inside a transaction it would create several new entities and reference them in other newly created entities. The problem got so bad, that the whole application had responsive problems because the NodeJS event loop was blocked with all the merge operations of Typeorm.

It seems Typeorm does something with the object instances of references of the entity where it goes recursively through them or something like this.

I kind of solved it by doing two things: replace create() with new Entity like you did and also replace save with insert. Original:

let entity = man.create(Entity, {
  prop1: "something",
  prop2: 42,
  ref1: someOtherEntityInstance
};
entity = await man.save(Entity, entity); // set ID of new created entity

// ...
let anotherEntity = man.create(AnotherEntity, {
  ref2: entity,
  prop3: true,
};
anotherEntity = await man.save(Entity, entity);

Version that works for me

const entity = new Entity();
entity.prop1 = "something";
entity.prop2 = 42;
entity.ref1 = new SomeOtherEntity();
entity.ref1.id = someOtherEntityInstance.id;

let insertInfo = await man.insert(Entity, entity);
entity.id = (insertInfo.identifiers[0] as { id: number }).id;

const anotherEntity = new AnotherEntity();
anotherEntity.prop3 = true;
anotherEntity.ref2 = new Entity();
anotherEntity.ref2.id = entity.id;

insertInfo = await man.insert(Entity, entity);
anotherEntity.id = (insertInfo.identifiers[0] as { id: number }).id;

Makes the code a lot more ugly but it runs without any problems now.