Doctrine entities give a Symfony application PHP classes for database-backed data. A mapped entity lets controllers, forms, fixtures, and repositories work with an object such as Article while Doctrine ORM handles the table and column metadata.

MakerBundle generates the entity class, repository class, getter and setter methods, and Doctrine ORM attributes for each field. In a standard Symfony Flex project, the generated files live under src/Entity and src/Repository, and Doctrine's naming strategy turns the class and property names into table and column names.

Creating the entity updates PHP metadata only. Keep the database connection configured before generating migrations, validate the mapping first, and create a migration when the entity shape is ready for a table change.

Steps to create a Doctrine entity in Symfony:

  1. Open a terminal in the Symfony project root that contains bin/console.
  2. Generate the Article entity with MakerBundle.
    $ php bin/console make:entity Article
     created: src/Entity/Article.php
     created: src/Repository/ArticleRepository.php
    
     Entity generated! Now let's add some fields!
    
     New property name (press <return> to stop adding fields):
     > title
     Field type (enter ? to see all types) [string]:
     > string
     Field length [255]:
     > 180
     Can this field be null in the database (nullable) (yes/no) [no]:
     > no
     updated: src/Entity/Article.php
    
     Add another property? Enter the property name (or press <return> to stop adding fields):
     > publishedAt
     Field type (enter ? to see all types) [datetime_immutable]:
     > datetime_immutable
     Can this field be null in the database (nullable) (yes/no) [no]:
     > yes
     updated: src/Entity/Article.php
    
     Add another property? Enter the property name (or press <return> to stop adding fields):
     >
    
      Success!
    
     Next: When you're ready, create a migration with php bin/console make:migration

    Use field names that match the domain language of the application. Avoid reserved SQL keywords for entity, table, and column names unless the project intentionally overrides those names in the mapping.

  3. Confirm that the entity and repository files exist.
    $ ls src/Entity/Article.php src/Repository/ArticleRepository.php
    src/Entity/Article.php
    src/Repository/ArticleRepository.php
  4. Review the generated entity mapping.
    Article.php
    <?php
     
    namespace App\Entity;
     
    use App\Repository\ArticleRepository;
    use Doctrine\ORM\Mapping as ORM;
     
    #[ORM\Entity(repositoryClass: ArticleRepository::class)]
    class Article
    {
        #[ORM\Id]
        #[ORM\GeneratedValue]
        #[ORM\Column]
        private ?int $id = null;
     
        #[ORM\Column(length: 180)]
        private ?string $title = null;
     
        #[ORM\Column(nullable: true)]
        private ?\DateTimeImmutable $publishedAt = null;
    }

    The #[ORM\Column] attributes record the database field type, length, and nullability. repositoryClass links the entity to ArticleRepository for query methods.

  5. Confirm that Doctrine discovers the new entity metadata.
    $ php bin/console doctrine:mapping:info
    Found 1 mapped entities:
    
    [OK]   App\Entity\Article
  6. Validate the entity mapping before creating the table.
    $ php bin/console doctrine:schema:validate --skip-sync
    Mapping
    -------
    
     [OK] The mapping files are correct.
    
    Database
    --------
    
     [SKIPPED] The database was not checked for synchronicity.

    --skip-sync checks the mapping without failing because the database table has not been created yet.

  7. Generate a migration diff when the entity shape is ready.
    $ php bin/console make:migration --formatted
     created: migrations/Version20260625074119.php
    
      Success!
    
     Review the new migration then run it with php bin/console doctrine:migrations:migrate
     See https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html

    Review the generated migration before applying it, especially in applications that already have production data.
    Related: How to create a Doctrine migration in Symfony
    Related: How to run Doctrine migrations in Symfony