Сообщество переполнения стека,
Я столкнулся с проблемой обработки UUID версии 4 в моем приложении Symfony при использовании Doctrine для извлечения связанных объектов из базы данных. Несмотря на настройку моих сущностей на использование UUID в качестве идентификаторов и обеспечение их поддержки моей базой данных, я продолжаю сталкиваться с проблемами преобразования.
Описание проблемы:
После перехода от использования строковых идентификаторов к UUID (v4) для идентификаторов объектов я столкнулся с постоянной проблемой, когда Doctrine, похоже, неправильно обрабатывает преобразование UUID, особенно при извлечении связанных объектов. Ошибка проявляется в том, что Doctrine генерирует запрос с UUID в двоичном формате (например, 0x546970E77A10401388351FA21F92E31A), который не соответствует ни одной записи из-за несоответствия формата.
Наиболее заметное влияние наблюдается при попытке использовать метод getEmailsTo() к моей сущности EmailFormType для извлечения связанных EmailTo сущностей. Метод возвращает нулевые значения, что указывает на то, что записи не найдены, предположительно из-за проблемы с форматом UUID.
Соответствующие фрагменты кода:
Объект EmailFormType (упрощенный):
#[ORM\Entity(repositoryClass: EmailFormTypeRepository::class)]
#[ORM\Table(name: 'WORKSPACE_EMAIL_FORM_TYPE')]
class EmailFormType {
#[ORM\Id]
#[ORM\Column(name:"id", type: UuidType::NAME, unique: true, nullable: false)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private Uuid $id;
// Other properties and methods...
/**
* @var Collection
*/
#[ORM\OneToMany(mappedBy: 'emailFormType', targetEntity: EmailTo::class)]
private Collection $emailsTo;
/**
*
*/
public function __construct()
{
$this->emailsTo = new ArrayCollection();
}
public function getEmailsTo(): Collection
{
return $this->emailsTo;
}
}
Функция получения писем:
public function getFormattedEmails(EmailFormType $emailFormType, string $type): string {
return implode(';', $emailFormType->getEmailsTo()
->filter(fn(EmailTo $emailTo) => $emailTo->getType() === $type)
->map(fn(EmailTo $emailTo) => $emailTo->getEmail())
->toArray());
}
Мое поле в моей базе данных ORACLE:
ИД --- VARCHAR2(100)
Выполненный запрос:
SELECT t0.id AS ID_1, t0.email AS EMAIL_2, t0.type AS TYPE_3, t0.email_form_type_id AS EMAIL_FORM_TYPE_ID_4 FROM WORKSPACE_EMAIL_TO t0 WHERE t0.email_form_type_id = 0x546970E77A10401388351FA21F92E31A;
Любая помощь или рекомендации по этому вопросу будут очень признательны!




Я столкнулся с проблемой при попытке сохранить тип VARCHAR2(100) для поля идентификатора моей сущности в базе данных ORACLE, и вот как я ее решил, обеспечив правильную обработку UUID:
doctrine.yaml.Вот класс, представляющий тип моего настраиваемого поля:
<?php
namespace App\Doctrine;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Symfony\Component\Uid\Uuid;
class CustomUuidType extends Type
{
public function convertToDatabaseValue($value, AbstractPlatform $platform): mixed
{
return $value instanceof Uuid ? $value->toRfc4122() : $value;
}
// Ensure this method can return null for nullable fields
public function convertToPHPValue($value, AbstractPlatform $platform): ?Uuid
{
return $value === null ? null : Uuid::fromString($value);
}
public function getName(): string
{
return 'custom_uuid';
}
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
{
return $platform->getColumnDeclarationSQL('varchar', $column);
}
}
Модификация файла doctrine.yaml:
doctrine:
dbal:
types:
custom_uuid: App\Doctrine\CustomUuidType
Моя настройка объекта:
#[ORM\Entity(repositoryClass: EmailFormTypeRepository::class)]
#[ORM\Table(name: 'WORKSPACE_EMAIL_FORM_TYPE')]
class EmailFormType
{
#[ORM\Id]
#[ORM\Column(name:"id", type:"custom_uuid", length: 100, unique: true, nullable: false)]
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private Uuid $id;
#[ORM\OneToMany(mappedBy: 'emailFormType', targetEntity: EmailTo::class)]
private Collection $emailsTo;
public function __construct()
{
$this->emailsTo = new ArrayCollection();
}
public function getId(): Uuid
{
return $this->id;
}
public function getEmailsTo(): Collection
{
return $this->emailsTo;
}
}
Благодаря этим изменениям Doctrine теперь правильно выполняет запросы с правильной обработкой преобразования UUID:
SELECT t0.id AS ID_1, t0.email AS EMAIL_2, t0.type AS TYPE_3, t0.email_form_type_id AS EMAIL_FORM_TYPE_ID_4 FROM WORKSPACE_EMAIL_TO t0 WHERE t0.email_form_type_id = ?
Parameters:
[
"546970e7-7a10-4013-8835-1fa21f92e31a"
]
Эта настройка гарантирует, что мое приложение правильно обрабатывает UUID как VARCHAR2(100) в базе данных, одновременно используя мощные возможности Symfony Doctrine ORM.