Skip to content

JoinedSubclassPersister::delete does not pass $types argument to Connection::delete #5988

@fred-jan

Description

@fred-jan

My entity uses both class table inheritance and a custom id type (uuid_binary type provided by the ramsey/uuid-doctrine package). Simplified example:

/**
 * @ORM\Entity
 * @ORM\Table(name="my_entity")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({
 *     "a" = "MyEntityA",
 *     "b" = "MyEntityB"
 * })
 */
abstract class MyEntity
{
    /**
     * @ORM\Id
     * @ORM\Column(type="uuid_binary")
     * @ORM\GeneratedValue(strategy="NONE")
     *
     * @var UuidInterface
     */
    private $id;
}

When I attempt to delete such an entity using the EntityManager, the JoinedSubclassPersister class is leveraged internally to perform the deletion and calls Connection::delete without passing along any field-mapping information as $types argument. This results in the following query being executed:

DELETE FROM my_entity WHERE id = 'Object(Ramsey\\Uuid\\Uuid)';

For my specific platform (which supports FK's) I've made a temporary fix by copying the $types assignment code from the BasicEntityPersister class, which looks like this:

        // ...
        // If the database platform supports FKs, just
        // delete the row from the root table. Cascades do the rest.
        if ($this->platform->supportsForeignKeyConstraints()) {
            $rootClass  = $this->em->getClassMetadata($this->class->rootEntityName);
            $rootTable  = $this->quoteStrategy->getTableName($rootClass, $this->platform);
            $types      = array_map(function ($identifier) use ($rootClass) {
                if (isset($rootClass->fieldMappings[$identifier])) {
                    return $rootClass->fieldMappings[$identifier]['type'];
                }

                $targetMapping = $this->em->getClassMetadata($rootClass->associationMappings[$identifier]['targetEntity']);

                if (isset($targetMapping->fieldMappings[$targetMapping->identifier[0]])) {
                    return $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
                }

                if (isset($targetMapping->associationMappings[$targetMapping->identifier[0]])) {
                    return $targetMapping->associationMappings[$targetMapping->identifier[0]]['type'];
                }

                throw ORMException::unrecognizedField($targetMapping->identifier[0]);

            }, $rootClass->identifier);

            return (bool) $this->conn->delete($rootTable, $id, $types);
        }
        // ...

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions