Symfony: Automatisch generierte UUID zusätzlich zu auto_increment id property
In einem meiner Projekte wollte ich einem meiner Models, das bereits eine `id` mit auto_increment besaß, eine UUID oder GUID hinzufügen. Offensichtlich ist es allerdings nicht erlaubt bzw. nicht möglich mehrere Properties mit der `@GeneratedValue` Annotation zu versehen.
Alle Code-Beispiele, die ich dazu gefunden habe, haben allerdings die UUID immer manuell im Controller-Code erzeugt und dann im Model gesetzt. Da im Projekt allerdings sowohl ein Web-Interface als auch eine ReST-API vorhanden ist, wollte ich die Generierung gerne zentral und automatisch haben. Die Lösung, zu der ich bekommen bin, nutzt Symfony's/Doctrine's Event System. Ich habe mich in diesem Fall für die Doctrine Entity Listener entschieden.
In meinem Model, habe ich die Property `uid` hinzugefügt:
<?php
namespace MyVendor\MyProject\Entity;
// ...
use Symfony\Component\Uid\Uuid;
// ...
class MyModel {
// ...
/**
* @ORM\Column(type="uuid")
*/
private Uuid $uid;
// ...
public function getUid(): Uuid
{
return $this->uid;
}
public function setUid(Uuid $uid): MyModel
{
$this->uid = $uid;
return $this;
}
// ...
}
Den Listener habe wie folgt implementiert:
<?php
declare(strict_types=1);
namespace MyVendor\MyProject\EventListener;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use MyVendor\MyProject\Entity\MyModel;
use Symfony\Component\Uid\Factory\UuidFactory;
class MyModelPersistenceListener
{
protected UuidFactory $uuidFactory;
/**
* @param UuidFactory $uuidFactory
*/
public function __construct(UuidFactory $uuidFactory)
{
$this->uuidFactory = $uuidFactory;
}
public function prePersist(MyModel $model, LifecycleEventArgs $lifecycleEventArgs)
{
$model->setUid($this->uuidFactory->create());
}
}
In der `services.yaml` habe ich den Listener folgender Maßen registriert:
# ...
MyVendor\MyProject\EventListener\MyModelPersistenceListener:
tags:
-
name: 'doctrine.orm.entity_listener'
event: 'prePersist'
entity: 'MyVendor\MyProject\Entity\MyModel'
# ...
Für manche ist die Lösung vielleicht offensichtlich. Ich habe dennoch einen Moment gebraucht, um darauf zu kommen. Daher dachte ich mir, ich das Teile meine Erkenntnisse mit euch.
Diese Website verwendet Disqus um Kommentare anzuzeigen. Aufgrund der geltenden Datenschutzgesetzte (DSGVO) musst du dem Laden der Kommentare von Disqus explizit zustimmen.
Kommentare anzeigen