Skip to content

BackedEnum primary key fails to convert for association using proxy classes #10788

@wmouwen

Description

@wmouwen

Bug Report

Q A
BC Break unsure
Version 2.15.3

Summary

For a while BackedEnums were allowed as primary keys, where Doctrine would happily convert them to their scalar value. There has been some back and forth about this in previous issues/PRs where the functionality was repaired and broken again.

#10334
#10471
#10508

Most recent events:
#10745
#10758

Current behavior

Setting a BackedEnum as primary key on an entity, using that entity in an association and trying to save it with a proxy class, will throw an error as the BackedEnum is no longer converted to a scalar value.

Uncaught Error: Object of class Enum\LocaleCode could not be converted to string in /app/vendor/doctrine/dbal/src/Driver/PDO/Statement.php:43
Stack trace:
#0 /app/vendor/doctrine/dbal/src/Driver/PDO/Statement.php(43): PDOStatement->bindValue(1, Object(Enum\LocaleCode), 2)
#1 /app/vendor/doctrine/dbal/src/Statement.php(115): Doctrine\DBAL\Driver\PDO\Statement->bindValue(1, Object(Enum\LocaleCode), 2)
#2 /app/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(276): Doctrine\DBAL\Statement->bindValue(1, Object(Enum\LocaleCode), Object(Doctrine\DBAL\Types\StringType))
#3 /app/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(1172): Doctrine\ORM\Persisters\Entity\BasicEntityPersister->executeInserts()
#4 /app/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php(441): Doctrine\ORM\UnitOfWork->executeInserts(Object(Doctrine\ORM\Mapping\ClassMetadata))
#5 /app/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(403): Doctrine\ORM\UnitOfWork->commit(NULL)
#6 /app/trigger_error.php(23): Doctrine\ORM\EntityManager->flush()
#7 {main}
  thrown in /app/vendor/doctrine/dbal/src/Driver/PDO/Statement.php on line 43

How to reproduce

See https://github.com/wmouwen/doctrine-orm-10788 for a minimal setup throwing the error.

Code snippet copy 👇
<?php

enum LocaleCode: string
{
    case Dutch = 'nl_NL';
}

#[ORM\Entity, ORM\Table]
class Locale
{
    #[ORM\Id]
    #[ORM\Column(name: 'code', type: Types::STRING, enumType: LocaleCode::class)]
    public LocaleCode $code;
}

#[ORM\Entity, ORM\Table]
class CategoryLocale
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(name: 'id', type: Types::INTEGER)]
    public int $id;

    #[ORM\ManyToOne(targetEntity: \Entity\Locale::class, cascade: ['persist'])]
    #[ORM\JoinColumn(name: 'locale_code', referencedColumnName: 'code', nullable: false)]
    public Locale $locale;
}
global $entityManager;

// Create entity with BackedEnum as primary key.
$locale = new \Entity\Locale();
$locale->code = \Enum\LocaleCode::Dutch;

// Persist entity, clear manager.
$entityManager->persist($locale);
$entityManager->flush();
$entityManager->clear();

// Create entity with an association to the entity with BackedEnum key.
// Note that the use of a proxy class is required for the error to show.
$categoryLocale = new \Entity\CategoryLocale();
$categoryLocale->locale = $entityManager->getReference(\Entity\Locale::class, \Enum\LocaleCode::Dutch);

// Attempt to persist, throws an error.
$entityManager->persist($categoryLocale);
$entityManager->flush();

Expected behavior

The BackedEnum is converted and the save succeeds, as it did in version 2.15.2.

-edit- Added the stack trace, made the code snippet collapse, added reference to repository with minimal setup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions