Propel 1.7 OutOfMemoryException from cross-ref add
jwong-dayspring opened this issue · 0 comments
I have a CrossRef table users_roles
that joins my users
and roles
tables. Propel generates User::addRole() and Role::addUser() functions in the Base object.
With a large dataset, calling User::addRole() results in PHP running out of memory. The same code works just fine with a smaller dataset, or with Propel 1.6.x.
Propel 1.7 sets the back reference when adding on a CrossRef object. In my project, this adds a $role->getUsers()
call to User::doAddRole(). Adding a role to a user ends up fetching all users that with that role.
In my case, I don't need the back reference counts to be updated. Since the problem code is in the Base class, I was able to override doAddRole() in the subclass.
I replaced the generated code:
protected function doAddRole(Role $role)
{
// set the back reference to this object directly as using provided method either results
// in endless loop or in multiple relations
if (!$role->getUsers()->contains($this)) { $userRole = new UserRole();
$userRole->setRole($role);
$this->addUserRole($userRole);
$foreignCollection = $role->getUsers();
$foreignCollection[] = $this;
}
}
with (same as what Propel 1.6.x generated):
protected function doAddRole(Role $role)
{
$userRole = new UserRole();
$userRole->setRole($role);
$this->addUserRole($userRole);
}
Initially it didn't seem like $foreignCollection was necessary, but it updates the PropelObjectCollection held by Role and subsequent calls to getUsers() returns the updated collection, including the User the role was just added to.
I can see why setting the back reference is helpful, but #677/#678 introduces a nasty side-effect for lookup table relationships and large databases.
See PHP5ObjectBuilder::addCrossFKDoAdd()