Skip to content

[Doctrine] Deprecate the reverse engineering docs #16924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 7 additions & 108 deletions doctrine/reverse_engineering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,114 +4,13 @@
How to Generate Entities from an Existing Database
==================================================

When starting work on a brand new project that uses a database, two different
situations can occur. In most cases, the database model is designed
and built from scratch. Sometimes, however, you'll start with an existing and
probably unchangeable database model. Fortunately, Doctrine comes with a bunch
of tools to help generate model classes from your existing database.
.. caution::

.. note::
The ``doctrine:mapping:import`` command used to generate Doctrine entities
from existing databases was deprecated by Doctrine in 2019 and it's no
longer recommended to use it.

As the `Doctrine tools documentation`_ says, reverse engineering is a
one-time process to get started on a project. Doctrine is able to convert
approximately 70-80% of the necessary mapping information based on fields,
indexes and foreign key constraints. Doctrine can't discover inverse
associations, inheritance types, entities with foreign keys as primary keys
or semantical operations on associations such as cascade or lifecycle
events. Some additional work on the generated entities will be necessary
afterwards to design each to fit your domain model specificities.
Instead, you can use the ``make:entity`` command from `Symfony Maker Bundle`_
to quickly generate the Doctrine entities of your application.

This tutorial assumes you're using a simple blog application with the following
two tables: ``blog_post`` and ``blog_comment``. A comment record is linked
to a post record thanks to a foreign key constraint.

.. code-block:: sql

CREATE TABLE `blog_post` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`content` longtext COLLATE utf8_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `blog_comment` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`post_id` bigint(20) NOT NULL,
`author` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`content` longtext COLLATE utf8_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `blog_comment_post_id_idx` (`post_id`),
CONSTRAINT `blog_post_id` FOREIGN KEY (`post_id`) REFERENCES `blog_post` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Before diving into the recipe, be sure your database connection parameters are
correctly set up in the ``.env`` file (or ``.env.local`` override file).

The first step towards building entity classes from an existing database
is to ask Doctrine to introspect the database and generate the corresponding
metadata files. Metadata files describe the entity class to generate based on
table fields.

.. code-block:: terminal

$ php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity

This command line tool asks Doctrine to introspect the database and generate
new PHP classes with annotation metadata into ``src/Entity``. This generates two
files: ``BlogPost.php`` and ``BlogComment.php``.

.. tip::

It's also possible to generate the metadata files into XML or eventually into YAML:

.. code-block:: terminal

$ php bin/console doctrine:mapping:import "App\Entity" xml --path=config/doctrine

In this case, make sure to adapt your mapping configuration accordingly:

.. code-block:: yaml

# config/packages/doctrine.yaml
doctrine:
# ...
orm:
# ...
mappings:
App:
is_bundle: false
type: xml # "yml" is marked as deprecated for doctrine v2.6+ and will be removed in v3
dir: '%kernel.project_dir%/config/doctrine'
prefix: 'App\Entity'
alias: App

Generating the Getters & Setters or PHP Classes
-----------------------------------------------

The generated PHP classes now have properties and annotation metadata, but they
do *not* have any getter or setter methods. If you generated XML or YAML metadata,
you don't even have the PHP classes!

To generate the missing getter/setter methods (or to *create* the classes if necessary),
run:

.. code-block:: terminal

// generates getter/setter methods for all Entities
$ php bin/console make:entity --regenerate App

// generates getter/setter methods for one specific Entity
$ php bin/console make:entity --regenerate "App\Entity\Country"

.. note::

If you want to have a OneToMany relationship, you will need to add
it manually into the entity (e.g. add a ``comments`` property to ``BlogPost``)
or to the generated XML or YAML files. Add a section on the specific entities
for one-to-many defining the ``inversedBy`` and the ``mappedBy`` pieces.

The generated entities are now ready to be used. Have fun!

.. _`Doctrine tools documentation`: https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/tools.html#reverse-engineering
.. _`Symfony Maker Bundle`: https://symfony.com/bundles/SymfonyMakerBundle/current/index.html