Skip to content

"preRemove" given wrong entity #7806

Open
@justin-nl

Description

@justin-nl

Bug Report

Q A
BC Break no?
Version 2.4.8 (and 2.5)

Summary

I'm working in Symfony 2.8 (and 3.4), with an Invoice entity that has a OneToOne with a File entity (for a PDF upload). I'm cascading "all" from Invoice to File.

The File entity is implementing the PostRemove callback for deleting the physical file after the DB is updated. Sometimes, this is called on the wrong entity, resulting in the wrong file being deleted.

Current behavior

The PostRemove callback is called on the wrong File entity. This results in the wrong physical file being removed. The correct parent Invoice and child File entities are removed from the DB.

It seems related to recent/subsequent entity creation. I would create a few invoices. Delete one. Load another, and find that the file could not be found.

Oddly enough, once I implemented the "PreRemove" (simply for debugging which entity I was working with), the "PostRemove" suddenly worked as expected. Basically, an empty "PreRemove" function "magically" made things work.

My ultimate work-around was to store the filename in a class variable in the "PreRemove" callback, and use that variable to determine which file is deleted in the "PostRemove" callback.

How to reproduce

In the Invoice entity:

/**
 * @ORM\OneToOne(targetEntity="File", cascade={"all"})
 * @ORM\JoinColumn(name="pdf_id", referencedColumnName="id")
 */
protected $pdf;

In the File entity:

/**
 * @ORM\PostRemove()
 */
public function postRemove()
{
    // "getAbsolutePath()" uses the "path" variable from the file object
    // and prepends the local system path
    $file = $this->getAbsolutePath();
    if (null !== $file) {
        // i did a `var_dump($file); exit;` to show the wrong filepath

        // "fs()" returns a new `Symfony\Component\Filesystem\Filesystem`
        $this->fs()->remove($file);
    }
}

Simple deletion using the Entity Manager:

// i verified here that the associations were correct
$em->remove($invoice);
// i verified here that the associations were still correct
$em->flush();
// i never got here because of the `exit;` I had implemented above

Expected behavior

I expect if I'm cascading from a parent object, the resulting PostRemove should be called on the correct child object.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions