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

Open
opened 2026-01-22 15:46:00 +01:00 by admin · 0 comments
Owner

Originally created by @wmouwen on GitHub (Jun 22, 2023).

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.

https://github.com/doctrine/orm/issues/10334
https://github.com/doctrine/orm/issues/10471
https://github.com/doctrine/orm/pull/10508

Most recent events:
https://github.com/doctrine/orm/issues/10745
https://github.com/doctrine/orm/pull/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.

Originally created by @wmouwen on GitHub (Jun 22, 2023). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | 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. https://github.com/doctrine/orm/issues/10334 https://github.com/doctrine/orm/issues/10471 https://github.com/doctrine/orm/pull/10508 Most recent events: https://github.com/doctrine/orm/issues/10745 https://github.com/doctrine/orm/pull/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. <details> <summary>Code snippet copy 👇</summary> ```php <?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; } ``` ```php 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(); ``` </details> #### 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._
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7171