propelorm / Propel2

Propel2 is an open-source high-performance Object-Relational Mapping (ORM) for modern PHP
http://propelorm.org/
MIT License
1.26k stars 396 forks source link

Propel2 hydrate a lot of useless objects in many-to-many relations #1303

Open angelk opened 7 years ago

angelk commented 7 years ago

Hello,

I have simple many-to-many relation. Lyric - language. I have ~30k lyrics. When I update language of single lyrics, e.g.

$lyric->setLanguages($languages);

Propel hydrate all 30k lyrics!

I wrote simple Dockerfile reproducing the issue: https://gist.github.com/angelk/c1aca7ef5c466f49eb01bfad7db7c308

Memory usage before and after the setter:

Before setPeak usage 4.4862 MB
After setPeak usage 87.1722 MB

php file testcase: https://gist.github.com/angelk/63f54ae8f38242170a1d3f18101e36dc Schema: in Dockerfile Tested on php 5.6 and 7.0 Branch master

angelk commented 7 years ago

I think the problem is somewhere here:https://github.com/propelorm/Propel2/blob/master/src/Propel/Generator/Builder/Om/ObjectBuilder.php#L5393

$getterSignature should apply filter but it doesn't. $this->getCrossFKGetterSignature($crossFKs, '$' . $lowerRelatedObjectClassName); return empty string.

marcj commented 7 years ago

setLanguages loads first getLanguages (the question is here, how many languages to you have for this particular lyric?) and then generates a diff to see which language needs to be removed. I don't think it loads all 30k lyrics.

angelk commented 7 years ago

In the testcase every lyric have exactly 1 language (id=1) - https://gist.github.com/angelk/63f54ae8f38242170a1d3f18101e36dc#file-propel2-memory-leak-testcase-L54-L56

In the test I change language to id=2 - https://gist.github.com/angelk/63f54ae8f38242170a1d3f18101e36dc#file-propel2-memory-leak-testcase-L74-L85

angelk commented 7 years ago

Just created example of the bug in the sandox - http://sandbox.propelorm.org/d091c10