2.13.2 - 2.13.3 | Enum column - Object of class x could not be converted to x #7046

Closed
opened 2026-01-22 15:43:39 +01:00 by admin · 14 comments
Owner

Originally created by @ThomasGoffart on GitHub (Sep 26, 2022).

Bug Report

Q A
BC Break yes
Version 2.13.2 - 2.13.3

Summary

When having an enum column like this:

#[ORM\Column(enumType: Color::class)]
private Color $color;

This error occurred when you load the entity from a query from the Query Builder (repository):

Warning: Object of class App\Enum\Color could not be converted to int

Workaround

Downgrade doctrine/orm to 2.13.1 version while waiting for a fix.

Originally created by @ThomasGoffart on GitHub (Sep 26, 2022). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | yes | Version | 2.13.2 - 2.13.3 #### Summary When having an enum column like this: ```php #[ORM\Column(enumType: Color::class)] private Color $color; ``` This error occurred when you load the entity from a query from the Query Builder (repository): > Warning: Object of class App\Enum\Color could not be converted to int #### Workaround Downgrade `doctrine/orm` to 2.13.1 version while waiting for a fix.
admin closed this issue 2026-01-22 15:43:40 +01:00
Author
Owner

@michnovka commented on GitHub (Sep 26, 2022):

This is also likely to be fixed with https://github.com/doctrine/orm/pull/10058 . Please confirm

@michnovka commented on GitHub (Sep 26, 2022): This is also likely to be fixed with https://github.com/doctrine/orm/pull/10058 . Please confirm
Author
Owner

@NotionCommotion commented on GitHub (Sep 26, 2022):

I am getting the same error, and when I comment out $this->rsm->addEnumResult($columnAlias, $mapping['enumType']); on line number 1525 added by this commit, I no longer get the error.

namespace Doctrine\ORM\Query;
class SqlWalker implements TreeWalker
{
    public function walkSelectExpression($selectExpression)
    {
                    ...
                    if (! empty($mapping['enumType'])) {
                        $this->rsm->addEnumResult($columnAlias, $mapping['enumType']);
                    }
                    ...
	}
}

Note that for my case, Doctrine tries to typecast PermissionEnum to an integer

namespace Doctrine\DBAL\Types;
class SmallIntType extends Type implements PhpIntegerMappingType
{
    ...
	public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value === null ? null : (int) $value;
    }
    ...
}

resulting in error Warning: Object of class App\\Entity\AccessControl\Acl\PermissionEnum could not be converted to int.

However, as shown below, PermissionEnum is never intended to be directly persisted in the database but only as a subpart in Permission.

namespace App\Doctrine\Types;

use App\Entity\AccessControl\Acl\Permission;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException;
use Doctrine\DBAL\Types\Type;

final class PermissionType extends Type
{
    private const PERMISSION = 'permission';

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
    {
        return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
    }

    public function convertToPHPValue($value, AbstractPlatform $platform): mixed
    {
        if (null === $value) {
            return null;
        }

        if (\is_int($value)) {
            return Permission::createFromValue($value);
        }

        throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['int', 'null']);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed
    {
        if (null === $value) {
            return null;
        }

        if ($value instanceof Permission) {
            return $value->getValue();
        }

        throw ConversionException::conversionFailedInvalidType($value, $this->getName(), [Permission::class, 'null']);
    }

    public function requiresSQLCommentHint(AbstractPlatform $platform): bool
    {
        return true;
    }

    public function getName(): string
    {
        return self::PERMISSION;
    }
}
class Permission
{
    private const READ      = 0b0000000011;
    private const CREATE    = 0b0000001100;
    private const MODIFY    = 0b0000110000;
    private const DELETE    = 0b0011000000;
    private const COWORKER  = 0b0100000000; // Not currently used.
    private const OWNER     = 0b1000000000; // Not currently used.

    public function __construct(
        private ?PermissionEnum $read=null,
        private ?PermissionEnum $create=null,
        private ?PermissionEnum $modify=null,
        private ?PermissionEnum $delete=null,
        private ?bool $restrictToOwner=null,
        private ?bool $coworkers=null
    ) {
    }

    public function getValue(): ?int
    {
        if($this->hasNullValue()) {
            throw new Exception('Permission has NULL values.');
        }
        $rs = $this->read->value | $this->create->value << 2 | $this->modify->value << 4 | $this->delete->value << 6;
        $rs = $this->coworkers ? $rs | self::COWORKER : $rs & ~self::COWORKER;

        return $this->restrictToOwner ? $rs | self::OWNER : $rs & ~self::OWNER;
    }
}
enum PermissionEnum: int
{
    case public     = 0b00;
    case owner      = 0b01;
    case restrict   = 0b10;
    case extra      = 0b11; 
}
@NotionCommotion commented on GitHub (Sep 26, 2022): I am getting the same error, and when I comment out `$this->rsm->addEnumResult($columnAlias, $mapping['enumType']);` on line number 1525 added by [this commit](https://github.com/doctrine/orm/commit/bc7e252f00858950bd1fdc24c82ab1042b587288), I no longer get the error. ```php namespace Doctrine\ORM\Query; class SqlWalker implements TreeWalker { public function walkSelectExpression($selectExpression) { ... if (! empty($mapping['enumType'])) { $this->rsm->addEnumResult($columnAlias, $mapping['enumType']); } ... } } ``` Note that for my case, Doctrine tries to typecast `PermissionEnum` to an integer ```php namespace Doctrine\DBAL\Types; class SmallIntType extends Type implements PhpIntegerMappingType { ... public function convertToPHPValue($value, AbstractPlatform $platform) { return $value === null ? null : (int) $value; } ... } ``` resulting in error `Warning: Object of class App\\Entity\AccessControl\Acl\PermissionEnum could not be converted to int`. However, as shown below, `PermissionEnum` is never intended to be directly persisted in the database but only as a subpart in `Permission`. ```php namespace App\Doctrine\Types; use App\Entity\AccessControl\Acl\Permission; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\ConversionException; use Doctrine\DBAL\Types\Type; final class PermissionType extends Type { private const PERMISSION = 'permission'; public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string { return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration); } public function convertToPHPValue($value, AbstractPlatform $platform): mixed { if (null === $value) { return null; } if (\is_int($value)) { return Permission::createFromValue($value); } throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['int', 'null']); } public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed { if (null === $value) { return null; } if ($value instanceof Permission) { return $value->getValue(); } throw ConversionException::conversionFailedInvalidType($value, $this->getName(), [Permission::class, 'null']); } public function requiresSQLCommentHint(AbstractPlatform $platform): bool { return true; } public function getName(): string { return self::PERMISSION; } } ``` ```php class Permission { private const READ = 0b0000000011; private const CREATE = 0b0000001100; private const MODIFY = 0b0000110000; private const DELETE = 0b0011000000; private const COWORKER = 0b0100000000; // Not currently used. private const OWNER = 0b1000000000; // Not currently used. public function __construct( private ?PermissionEnum $read=null, private ?PermissionEnum $create=null, private ?PermissionEnum $modify=null, private ?PermissionEnum $delete=null, private ?bool $restrictToOwner=null, private ?bool $coworkers=null ) { } public function getValue(): ?int { if($this->hasNullValue()) { throw new Exception('Permission has NULL values.'); } $rs = $this->read->value | $this->create->value << 2 | $this->modify->value << 4 | $this->delete->value << 6; $rs = $this->coworkers ? $rs | self::COWORKER : $rs & ~self::COWORKER; return $this->restrictToOwner ? $rs | self::OWNER : $rs & ~self::OWNER; } } ``` ```php enum PermissionEnum: int { case public = 0b00; case owner = 0b01; case restrict = 0b10; case extra = 0b11; } ```
Author
Owner

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

@NotionCommotion Please provide a small application or a functional test case that reproduces your issue.

@derrabus commented on GitHub (Sep 27, 2022): @NotionCommotion Please provide a small application or a functional test case that reproduces your issue.
Author
Owner

@kshtompel commented on GitHub (Sep 27, 2022):

I see fix of this issue in this commit
d69a0fa2cf
but it was not released as 2.13.3
when to expect the release?

@kshtompel commented on GitHub (Sep 27, 2022): I see fix of this issue in this commit https://github.com/doctrine/orm/commit/d69a0fa2cfd3b883200a6324829945509f4ecc07 but it was not released as 2.13.3 when to expect the release?
Author
Owner

@devtronic commented on GitHub (Sep 28, 2022):

See also #10057

@devtronic commented on GitHub (Sep 28, 2022): See also #10057
Author
Owner

@NotionCommotion commented on GitHub (Sep 28, 2022):

@derrabus I spent about 4 hours yesterday trying to isolate the issue so I may provide it, but was unsuccessful. Didn't try everything such as checking whether some 3rd party app such as doctrine extensions is also involved. Any thoughts how one best troubleshoots and isolates issues such as this?

@NotionCommotion commented on GitHub (Sep 28, 2022): @derrabus I spent about 4 hours yesterday trying to isolate the issue so I may provide it, but was unsuccessful. Didn't try everything such as checking whether some 3rd party app such as doctrine extensions is also involved. Any thoughts how one best troubleshoots and isolates issues such as this?
Author
Owner

@kshtompel commented on GitHub (Oct 9, 2022):

@ThomasGoffart is it resolved now?

@kshtompel commented on GitHub (Oct 9, 2022): @ThomasGoffart is it resolved now?
Author
Owner

@greg0ire commented on GitHub (Oct 9, 2022):

Let me know if it is not resolved and I will reopen this.

@greg0ire commented on GitHub (Oct 9, 2022): Let me know if it is not resolved and I will reopen this.
Author
Owner

@ThomasGoffart commented on GitHub (Oct 11, 2022):

This issue is still on my side (doctrine/orm v2.13.3 )

@ThomasGoffart commented on GitHub (Oct 11, 2022): > This issue is still on my side (`doctrine/orm` v2.13.3 )
Author
Owner

@michnovka commented on GitHub (Oct 11, 2022):

Can you please provide your Color enum definition?

@michnovka commented on GitHub (Oct 11, 2022): Can you please provide your `Color` enum definition?
Author
Owner

@ThomasGoffart commented on GitHub (Oct 11, 2022):

This error occurs with a classic enum.
Here is a common example of enum that causes this problem.

<?php

namespace App\Enum;

enum Color: int {

    case Red = 1;
    case Green = 2;
    case Blue = 3;

}
@ThomasGoffart commented on GitHub (Oct 11, 2022): This error occurs with a classic enum. Here is a common example of enum that causes this problem. ```php <?php namespace App\Enum; enum Color: int { case Red = 1; case Green = 2; case Blue = 3; } ```
Author
Owner

@michnovka commented on GitHub (Oct 11, 2022):

Just out of curiosity, when using string backed enums, can you also reproduce the issue?

@michnovka commented on GitHub (Oct 11, 2022): Just out of curiosity, when using `string` backed enums, can you also reproduce the issue?
Author
Owner

@ThomasGoffart commented on GitHub (Oct 11, 2022):

Yes, I tested it and it also happens.

@ThomasGoffart commented on GitHub (Oct 11, 2022): Yes, I tested it and it also happens.
Author
Owner

@michnovka commented on GitHub (Oct 11, 2022):

Do these tests you submitted fail - https://github.com/doctrine/orm/pull/10111 ?

If they do not, can you please push PR with failing tests? I will work on it then.

@michnovka commented on GitHub (Oct 11, 2022): Do these tests you submitted fail - https://github.com/doctrine/orm/pull/10111 ? If they do not, can you please push PR with failing tests? I will work on it then.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7046