can not set default value to enum case #6906

Closed
opened 2026-01-22 15:41:04 +01:00 by admin · 8 comments
Owner

Originally created by @jgroc-de on GitHub (Jan 13, 2022).

Bug Report

Q A
BC Break no
Version 2.11.0

Summary

We dumbly tried to put a default value to a property set to a enum's case and
it does not work when generating the migration
which means we can not set default value based on enum case
(we can hardcode it but we are not happy with this solution)

Current behavior

given an enum:

enum Suit: string {
    case Hearts = 'hearts';
    case Diamonds = 'diamonds'; 
}

trying

    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": App\Enum\Suit::Hearts}
     * )
     */
    private Suit $suit = Suit::Hearts;

give us after a bin/console make:migration

In AbstractPlatform.php line 3913:
                                                                                                                      
  str_replace(): Argument #3 ($subject) must be of type array|string, App\Enum\Suit given 

trying

    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": "App\Enum\Suit::Hearts"}
     * )
     */
    private Suit $suit = Suit::Hearts;

give us a migration like

    public function up(Schema $schema): void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('ALTER TABLE entity ALTER suit SET DEFAULT \'App\\Enum\\Suit::Hearts\'');
    }

which is the string "App\Enum\Suit::Hearts" and not the value of the enum case

How to reproduce

create an enum:

enum Suit: string {
    case Hearts = 'hearts';
    case Diamonds = 'diamonds'; 
}

set a property in an entity linking to this enum
with a default value set to one of the enum case

    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": App\Enum\Suit::Hearts}
     * )
     */
    private Suit $suit = Suit::Hearts;

make a migration
(in sf5): bin/console make:migration

Expected behavior

trying

    /**
     * @ORM\Column(
     *      type="string",
     *      length=255,
     *      enumType="App\Enum\Suit",
     *      options={"default": App\Enum\Suit::Hearts}
     * )
     */
    private Suit $suit = Suit::Hearts;

give us a migration like

    public function up(Schema $schema): void
    {
        // this up() migration is auto-generated, please modify it to your needs
        $this->addSql('ALTER TABLE entity ALTER suit SET DEFAULT \'hearts\''');
    }
Originally created by @jgroc-de on GitHub (Jan 13, 2022). ### Bug Report | Q | A |------------ | ------ | BC Break | no | Version | 2.11.0 #### Summary We dumbly tried to put a default value to a property set to a enum's case and it does not work when generating the migration which means we can not set default value based on enum case (we can hardcode it but we are not happy with this solution) #### Current behavior given an enum: ``` enum Suit: string { case Hearts = 'hearts'; case Diamonds = 'diamonds'; } ``` trying ``` /** * @ORM\Column( * type="string", * length=255, * enumType="App\Enum\Suit", * options={"default": App\Enum\Suit::Hearts} * ) */ private Suit $suit = Suit::Hearts; ``` give us after a bin/console make:migration ``` In AbstractPlatform.php line 3913: str_replace(): Argument #3 ($subject) must be of type array|string, App\Enum\Suit given ``` trying ``` /** * @ORM\Column( * type="string", * length=255, * enumType="App\Enum\Suit", * options={"default": "App\Enum\Suit::Hearts"} * ) */ private Suit $suit = Suit::Hearts; ``` give us a migration like ``` public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs $this->addSql('ALTER TABLE entity ALTER suit SET DEFAULT \'App\\Enum\\Suit::Hearts\''); } ``` which is the string "App\\Enum\\Suit::Hearts\" and not the value of the enum case #### How to reproduce create an enum: ``` enum Suit: string { case Hearts = 'hearts'; case Diamonds = 'diamonds'; } ``` set a property in an entity linking to this enum with a default value set to one of the enum case ``` /** * @ORM\Column( * type="string", * length=255, * enumType="App\Enum\Suit", * options={"default": App\Enum\Suit::Hearts} * ) */ private Suit $suit = Suit::Hearts; ``` make a migration (in sf5): `bin/console make:migration` #### Expected behavior trying ``` /** * @ORM\Column( * type="string", * length=255, * enumType="App\Enum\Suit", * options={"default": App\Enum\Suit::Hearts} * ) */ private Suit $suit = Suit::Hearts; ``` give us a migration like ``` public function up(Schema $schema): void { // this up() migration is auto-generated, please modify it to your needs $this->addSql('ALTER TABLE entity ALTER suit SET DEFAULT \'hearts\'''); } ```
admin added the New Feature label 2026-01-22 15:41:04 +01:00
admin closed this issue 2026-01-22 15:41:05 +01:00
Author
Owner

@beberlei commented on GitHub (Jan 13, 2022):

@morozov I believe this could be best solved in DBAL Schema\Column by checking for a BackedEnum in the default value and resolving to $enum->value, what do you think?

@beberlei commented on GitHub (Jan 13, 2022): @morozov I believe this could be best solved in DBAL `Schema\Column` by checking for a `BackedEnum` in the default value and resolving to $enum->value, what do you think?
Author
Owner

@morozov commented on GitHub (Jan 13, 2022):

Normally, the DBAL doesn't perform any explicit downcasting of types (e.g. Stringable__toString()). Since this is the ORM that owns the support for enums, it seems to make more sense if the ORM checked for a BackedEnum and replaced it with the value. I wouldn't expect a BackedEnum to be used in the DBAL without the ORM.

@morozov commented on GitHub (Jan 13, 2022): Normally, the DBAL doesn't perform any explicit downcasting of types (e.g. `Stringable` → `__toString()`). Since this is the ORM that owns the support for enums, it seems to make more sense if the ORM checked for a `BackedEnum` and replaced it with the value. I wouldn't expect a `BackedEnum` to be used in the DBAL without the ORM.
Author
Owner

@derrabus commented on GitHub (Jan 14, 2022):

I'm not sure if we should treat this as a bug. I realize that the enum column feature feels a bit incomplete without the ability to specify an actual enum case as default. But so far, the default was something we had passed directly to the schema manager and if we start to preprocess it, we should make sure we do it right. One idea (not sure how feasible this is) could be to reuse the query parameter preprocessing here which will support enums in 2.12.

The workaround for now would be to use the backed value directly. That may not be nice, but it'll give us time to implement enum cases as default values properly for 2.12.

#[ORM\Column(
    type: 'string',
    length: 255,
    enumType: Suit::class,
    options: ['default' => 'hearts'],
)]
private Suit $suit = Suit::Hearts;
@derrabus commented on GitHub (Jan 14, 2022): I'm not sure if we should treat this as a bug. I realize that the enum column feature feels a bit incomplete without the ability to specify an actual enum case as default. But so far, the default was something we had passed directly to the schema manager and if we start to preprocess it, we should make sure we do it right. One idea (not sure how feasible this is) could be to reuse the query parameter preprocessing here which will support enums in 2.12. The workaround for now would be to use the backed value directly. That may not be nice, but it'll give us time to implement enum cases as default values properly for 2.12. ```PHP #[ORM\Column( type: 'string', length: 255, enumType: Suit::class, options: ['default' => 'hearts'], )] private Suit $suit = Suit::Hearts; ```
Author
Owner

@jgroc-de commented on GitHub (Jan 14, 2022):

As said, we dont like to put the default value directly.
So we had just drop the default value for now as we can live without it in our db, letting the entity setting the default value in the constructor.
And i agree, it's more like a "missing feature".

@jgroc-de commented on GitHub (Jan 14, 2022): As said, we dont like to put the default value directly. So we had just drop the default value for now as we can live without it in our db, letting the entity setting the default value in the constructor. And i agree, it's more like a "missing feature".
Author
Owner

@michaeldnelson commented on GitHub (Jan 26, 2022):

Hmmm. I came here to report this feature not functioning in the orm but from this thread it seems like it might just be me.

#[ORM\Column(type: 'string', length: 20, enumType: Visibility::class)]
public Visibility $visibility = Visibility::PRIVATE;

results in:

Proxies\__CG__\Model\Entities\Visibility not found

in the object hydrator. Does anyone know if this case should function? Must I include an options default value? I prefer to manage my defaults in code.

@michaeldnelson commented on GitHub (Jan 26, 2022): Hmmm. I came here to report this feature not functioning in the orm but from this thread it seems like it might just be me. ```php #[ORM\Column(type: 'string', length: 20, enumType: Visibility::class)] public Visibility $visibility = Visibility::PRIVATE; ``` results in: ```php Proxies\__CG__\Model\Entities\Visibility not found ``` in the object hydrator. Does anyone know if this case should function? Must I include an options default value? I prefer to manage my defaults in code.
Author
Owner

@ThomasLandauer commented on GitHub (Jan 27, 2022):

@michaeldnelson The enumType is working for me. The "Proxies" message sounds like you need to clear the cache ;-)

@ThomasLandauer commented on GitHub (Jan 27, 2022): @michaeldnelson The `enumType` is working for me. The "Proxies" message sounds like you need to clear the cache ;-)
Author
Owner

@derrabus commented on GitHub (Jan 27, 2022):

@michaeldnelson Your problem has nothing to do with the feature that is discussed here. Please open a new issue if you think it's a bug or a discussion if you seek support.

@derrabus commented on GitHub (Jan 27, 2022): @michaeldnelson Your problem has nothing to do with the feature that is discussed here. Please open a new issue if you think it's a bug or a discussion if you seek support.
Author
Owner

@derrabus commented on GitHub (Mar 28, 2022):

#9616

@derrabus commented on GitHub (Mar 28, 2022): #9616
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6906