DDC-3676: Entity executing UPDATE on Collection elements with PostLoad callback when cloning #4516

Closed
opened 2026-01-22 14:43:44 +01:00 by admin · 3 comments
Owner

Originally created by @doctrinebot on GitHub (Apr 8, 2015).

Originally assigned to: @Ocramius on GitHub.

Jira issue originally created by user webdevilopers:

My Branch entity has a collection of Contracts.
https://gist.github.com/webdevilopers/65716f36ac2249e5e899#file-branch-php

A Contract has a PostLoad event which is converting a legacy yaml database field to a readable format.
https://gist.github.com/webdevilopers/65716f36ac2249e5e899#file-contract-php

When cloning a Branch the database executes a single INSERT for the new branch successfully.
It does NOT persist any collection which is the expected behaviour since I guess relations have to be handled inside the **clone method separately.

But after the INSERT the database also fires an UPDATE on each Contract (currently *3000* related rows in database) updating the column that was converted inside the PostLoad event.

/****
* @ORM\PostLoad
*
* Legacy workaround converting custom fields yaml to aray
*/
public function convertCustomFieldsYamlToArray()
{
    $customFieldsYaml = $this->getCustomFields();
    if (empty($customFieldsYaml)) { return; }
    $customFields = yaml_parse($customFieldsYaml);
    $this->setCustomFields($customFields);
} 

I think calling the PostLoad is correct. But why is there an additional UPDATE called?

$em = $this->getDoctrine()->getManager();
$branch = $em->getRepository('AppBundle:Branch')->find(1);

dump($branch);
echo "Old ID:" . $branch->getId();

$newBranch = clone $branch;
dump($newBranch);

$em->persist($newBranch);
$em->flush();

dump($newBranch);
echo "<br>New Id:" . $newBranch->getId(); 

https://gist.github.com/webdevilopers/65716f36ac2249e5e899#file-branchcontroller-php

Maybe the flush recognizes changes in the original Branch entity and its Contract collection?

When I add a clear to my __clone method I get _9* instead of 3000 _UPDATE* queries:

    /****
     * @see http://doctrine-orm.readthedocs.org/en/latest/cookbook/implementing-wakeup-or-clone.html
     */
    public function **clone() {
        if ($this->id) {
            $this->contracts->clear();
        }
    }

These 9 remaing UPDATE are additionally fired by another callback:

    /****
     * @ORM\PrePersist
     * @ORM\PreUpdate
     *
     * Legacy workaround converting custom fields to yaml format utf8 encoded
     */
    public function convertCustomFieldsArrayToYaml()
    {
        $customFields = $this->getCustomFields();
        $customFieldsYaml = yaml*emit($customFields, YAML_UTF8*ENCODING);
        $this->setCustomFields($customFieldsYaml);
    }

In summary:
At the bottom line the _clone method causes *9 UPDATE queries for Pre* and 3000 (number of related database rows) for _PostLoad*.

Originally created by @doctrinebot on GitHub (Apr 8, 2015). Originally assigned to: @Ocramius on GitHub. Jira issue originally created by user webdevilopers: My `Branch` entity has a collection of `Contract`s. https://gist.github.com/webdevilopers/65716f36ac2249e5e899#file-branch-php A `Contract` has a **PostLoad** event which is converting a legacy yaml database field to a readable format. https://gist.github.com/webdevilopers/65716f36ac2249e5e899#file-contract-php When cloning a Branch the database executes a single _INSERT_ for the new branch successfully. It does NOT persist any collection which is the expected behaviour since I guess relations have to be handled inside the **clone method separately. But after the _INSERT_ the database also fires an _UPDATE_ on each Contract (currently <sub>**3000\* related rows in database) updating the column that was converted inside the *PostLoad** event. ``` /**** * @ORM\PostLoad * * Legacy workaround converting custom fields yaml to aray */ public function convertCustomFieldsYamlToArray() { $customFieldsYaml = $this->getCustomFields(); if (empty($customFieldsYaml)) { return; } $customFields = yaml_parse($customFieldsYaml); $this->setCustomFields($customFields); } ``` I think calling the **PostLoad** is correct. But why is there an additional _UPDATE_ called? ``` $em = $this->getDoctrine()->getManager(); $branch = $em->getRepository('AppBundle:Branch')->find(1); dump($branch); echo "Old ID:" . $branch->getId(); $newBranch = clone $branch; dump($newBranch); $em->persist($newBranch); $em->flush(); dump($newBranch); echo "<br>New Id:" . $newBranch->getId(); ``` https://gist.github.com/webdevilopers/65716f36ac2249e5e899#file-branchcontroller-php Maybe the _flush_ recognizes changes in the original _Branch_ entity and its _Contract_ collection? When I add a clear to my ___clone_ method I get </sub>_9\* instead of <sub>_3000_ _UPDATE\* queries: ``` /**** * @see http://doctrine-orm.readthedocs.org/en/latest/cookbook/implementing-wakeup-or-clone.html */ public function **clone() { if ($this->id) { $this->contracts->clear(); } } ``` These **9** remaing _UPDATE_ are additionally fired by another callback: ``` /**** * @ORM\PrePersist * @ORM\PreUpdate * * Legacy workaround converting custom fields to yaml format utf8 encoded */ public function convertCustomFieldsArrayToYaml() { $customFields = $this->getCustomFields(); $customFieldsYaml = yaml*emit($customFields, YAML_UTF8*ENCODING); $this->setCustomFields($customFieldsYaml); } ``` In summary: At the bottom line the ___clone_ method causes *9_ _UPDATE_ queries for _Pre*_ and </sub>_3000_ (number of related database rows) for _PostLoad*.
admin added the Bug label 2026-01-22 14:43:44 +01:00
admin closed this issue 2026-01-22 14:43:45 +01:00
Author
Owner

@doctrinebot commented on GitHub (Apr 8, 2015):

Comment created by @ocramius:

Resolving as invalid: please provide a small reproducible example that is not specific to your codebase.

As it stands, this seems more like a debugging request.

@doctrinebot commented on GitHub (Apr 8, 2015): Comment created by @ocramius: Resolving as invalid: please provide a small reproducible example that is not specific to your codebase. As it stands, this seems more like a debugging request.
Author
Owner

@doctrinebot commented on GitHub (Apr 8, 2015):

Issue was closed with resolution "Invalid"

@doctrinebot commented on GitHub (Apr 8, 2015): Issue was closed with resolution "Invalid"
Author
Owner

@doctrinebot commented on GitHub (Apr 8, 2015):

Comment created by webdevilopers:

Sure Marco, I will add some fixtures to my example to make it reproducable if that is enough for debugging?

@doctrinebot commented on GitHub (Apr 8, 2015): Comment created by webdevilopers: Sure Marco, I will add some fixtures to my example to make it reproducable if that is enough for debugging?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4516