Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Doctrine-Grundlagen: Entities definieren

Doctrine-Grundlagen: Entities definieren

~16 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

Endlich bekommt unser Aufgaben-Manager eine ECHTE Datenbank. Doctrine ist Symfonys Standard-ORM (Object-Relational Mapper) – PHP-Klassen werden zu Datenbanktabellen, OHNE eine einzige Zeile SQL von Hand zu schreiben.

Doctrine installieren

composer require symfony/orm-pack
composer require --dev symfony/maker-bundle

Die orm-pack-Recipe (Kapitel 6) richtet config/packages/doctrine.yaml und DATABASE_URL in .env automatisch ein – GENAU der Wert, den wir bereits in Kapitel 2 vorbereitet haben.

Die Project-Entity generieren

php bin/console make:entity Project
# Interaktiv abgefragt:
#   name (string, 255, nullable: no)
#   description (text, nullable: yes)
#   createdAt (datetime_immutable, nullable: no)

make:entity stellt interaktiv Fragen und generiert daraus die vollständige PHP-Klasse – ein bewusst geführter Prozess, den wir hier einmal manuell nachvollziehen, um zu verstehen, WAS dabei entsteht:

src/Entity/Project.php
<?php

declare(strict_types=1);

namespace App\Entity;

use App\Repository\ProjectRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ProjectRepository::class)]
class Project
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private string $name = '';

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $description = null;

    #[ORM\Column]
    private \DateTimeImmutable $createdAt;

    public function __construct()
    {
        $this->createdAt = new \DateTimeImmutable();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): static
    {
        $this->name = $name;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): static
    {
        $this->description = $description;

        return $this;
    }

    public function getCreatedAt(): \DateTimeImmutable
    {
        return $this->createdAt;
    }
}

Die Attribute im Detail

  • #[ORM\Entity] – markiert die Klasse als Doctrine-Entity, also als "wird in der Datenbank gespeichert".
  • #[ORM\Id] – dieses Feld ist der Primärschlüssel.
  • #[ORM\GeneratedValue] – die Datenbank vergibt den Wert automatisch (AUTO_INCREMENT/SEQUENCE).
  • #[ORM\Column] – dieses PHP-Property wird zu einer Datenbankspalte. Ohne explizite Optionen wird der Typ aus der PHP-Typdeklaration abgeleitet.

Das Fluent-Setter-Muster: return $this

setName() gibt $this zurück statt void – erlaubt VERKETTETE Aufrufe:

$projekt = (new Project())
    ->setName('Website-Relaunch')
    ->setDescription('Kompletter Redesign der Firmenwebsite');

getId() hat KEINEN Setter – die ID wird AUSSCHLIESSLICH von der Datenbank vergeben, niemals manuell gesetzt. Der Rückgabetyp ?int (nullable) spiegelt wider, dass eine NEUE, noch nicht gespeicherte Entity noch KEINE ID hat.

Das Mapping validieren

php bin/console doctrine:schema:validate

Tipp: Nützlich NACH jeder manuellen Änderung an einer Entity, um sicherzustellen, dass Doctrines interne Metadaten (aus den Attributen abgeleitet) konsistent sind, BEVOR eine Migration erstellt wird (Kapitel 20).

Die restlichen Entities im Vorgriff

In den kommenden Kapiteln entstehen analog: User (Kapitel 26, mit Security-Interfaces), Task (Kapitel 22, mit Beziehung zu Project), Comment (Kapitel 22/23) – GENAU das Domänenmodell aus Kapitel 5.