You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{"payload":{"allShortcutsEnabled":false,"fileTree":{"":{"items":[{"name":".github","path":".github","contentType":"directory"},{"name":".symfony","path":".symfony","contentType":"directory"},{"name":"_build","path":"_build","contentType":"directory"},{"name":"_images","path":"_images","contentType":"directory"},{"name":"_includes","path":"_includes","contentType":"directory"},{"name":"best_practices","path":"best_practices","contentType":"directory"},{"name":"bundles","path":"bundles","contentType":"directory"},{"name":"components","path":"components","contentType":"directory"},{"name":"configuration","path":"configuration","contentType":"directory"},{"name":"console","path":"console","contentType":"directory"},{"name":"contributing","path":"contributing","contentType":"directory"},{"name":"controller","path":"controller","contentType":"directory"},{"name":"create_framework","path":"create_framework","contentType":"directory"},{"name":"deployment","path":"deployment","contentType":"directory"},{"name":"doctrine","path":"doctrine","contentType":"directory"},{"name":"email","path":"email","contentType":"directory"},{"name":"event_dispatcher","path":"event_dispatcher","contentType":"directory"},{"name":"form","path":"form","contentType":"directory"},{"name":"frontend","path":"frontend","contentType":"directory"},{"name":"getting_started","path":"getting_started","contentType":"directory"},{"name":"http_cache","path":"http_cache","contentType":"directory"},{"name":"introduction","path":"introduction","contentType":"directory"},{"name":"logging","path":"logging","contentType":"directory"},{"name":"messenger","path":"messenger","contentType":"directory"},{"name":"profiler","path":"profiler","contentType":"directory"},{"name":"quick_tour","path":"quick_tour","contentType":"directory"},{"name":"reference","path":"reference","contentType":"directory"},{"name":"routing","path":"routing","contentType":"directory"},{"name":"security","path":"security","contentType":"directory"},{"name":"serializer","path":"serializer","contentType":"directory"},{"name":"service_container","path":"service_container","contentType":"directory"},{"name":"session","path":"session","contentType":"directory"},{"name":"setup","path":"setup","contentType":"directory"},{"name":"templating","path":"templating","contentType":"directory"},{"name":"testing","path":"testing","contentType":"directory"},{"name":"translation","path":"translation","contentType":"directory"},{"name":"validation","path":"validation","contentType":"directory"},{"name":"workflow","path":"workflow","contentType":"directory"},{"name":".editorconfig","path":".editorconfig","contentType":"file"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":".symfony.cloud.yaml","path":".symfony.cloud.yaml","contentType":"file"},{"name":".travis.yml","path":".travis.yml","contentType":"file"},{"name":"Dockerfile","path":"Dockerfile","contentType":"file"},{"name":"README.markdown","path":"README.markdown","contentType":"file"},{"name":"bundles.rst","path":"bundles.rst","contentType":"file"},{"name":"configuration.rst","path":"configuration.rst","contentType":"file"},{"name":"console.rst","path":"console.rst","contentType":"file"},{"name":"controller.rst","path":"controller.rst","contentType":"file"},{"name":"deployment.rst","path":"deployment.rst","contentType":"file"},{"name":"doctrine.rst","path":"doctrine.rst","contentType":"file"},{"name":"email.rst","path":"email.rst","contentType":"file"},{"name":"event_dispatcher.rst","path":"event_dispatcher.rst","contentType":"file"},{"name":"forms.rst","path":"forms.rst","contentType":"file"},{"name":"frontend.rst","path":"frontend.rst","contentType":"file"},{"name":"http_cache.rst","path":"http_cache.rst","contentType":"file"},{"name":"index.rst","path":"index.rst","contentType":"file"},{"name":"logging.rst","path":"logging.rst","contentType":"file"},{"name":"mercure.rst","path":"mercure.rst","contentType":"file"},{"name":"messenger.rst","path":"messenger.rst","contentType":"file"},{"name":"page_creation.rst","path":"page_creation.rst","contentType":"file"},{"name":"performance.rst","path":"performance.rst","contentType":"file"},{"name":"profiler.rst","path":"profiler.rst","contentType":"file"},{"name":"routing.rst","path":"routing.rst","contentType":"file"},{"name":"security.rst","path":"security.rst","contentType":"file"},{"name":"serializer.rst","path":"serializer.rst","contentType":"file"},{"name":"service_container.rst","path":"service_container.rst","contentType":"file"},{"name":"session.rst","path":"session.rst","contentType":"file"},{"name":"setup.rst","path":"setup.rst","contentType":"file"},{"name":"templating.rst","path":"templating.rst","contentType":"file"},{"name":"testing.rst","path":"testing.rst","contentType":"file"},{"name":"translation.rst","path":"translation.rst","contentType":"file"},{"name":"validation.rst","path":"validation.rst","contentType":"file"},{"name":"web_link.rst","path":"web_link.rst","contentType":"file"},{"name":"workflow.rst","path":"workflow.rst","contentType":"file"}],"totalCount":74}},"fileTreeProcessingTime":11.097622999999999,"foldersToFetch":[],"incompleteFileTree":false,"repo":{"id":12387477,"defaultBranch":"master","name":"symfony-docs","ownerLogin":"dunglas","currentUserCanPush":false,"isFork":true,"isEmpty":false,"createdAt":"2013-08-26T19:13:29.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/57224?v=4","public":true,"private":false,"isOrgOwned":false},"codeLineWrapEnabled":false,"symbolsExpanded":false,"treeExpanded":true,"refInfo":{"name":"f7b26a0d06aa6edb1aae777d74374042ef200216","listCacheKey":"v0:1747404158.0","canEdit":false,"refType":"tree","currentOid":"f7b26a0d06aa6edb1aae777d74374042ef200216"},"path":"doctrine.rst","currentUser":null,"blob":{"rawLines":null,"stylingDirectives":null,"colorizedLines":null,"csv":null,"csvError":null,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/dunglas/symfony-docs/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"doctrine.rst","displayUrl":"https://github.com/dunglas/symfony-docs/blob/f7b26a0d06aa6edb1aae777d74374042ef200216/doctrine.rst?raw=true","headerInfo":{"blobSize":"29.1 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":null,"isGitLfs":false,"onBranch":false,"shortPath":"bef0f14","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Fdunglas%2Fsymfony-docs%2Fblob%2Ff7b26a0d06aa6edb1aae777d74374042ef200216%2Fdoctrine.rst","isCSV":false,"isRichtext":true,"toc":[{"level":2,"text":"Databases and the Doctrine ORM","anchor":"databases-and-the-doctrine-orm","htmlText":"Databases and the Doctrine ORM"},{"level":3,"text":"Installing Doctrine","anchor":"installing-doctrine","htmlText":"Installing Doctrine"},{"level":4,"text":"Configuring the Database","anchor":"configuring-the-database","htmlText":"Configuring the Database"},{"level":3,"text":"Creating an Entity Class","anchor":"creating-an-entity-class","htmlText":"Creating an Entity Class"},{"level":3,"text":"Migrations: Creating the Database Tables/Schema","anchor":"migrations-creating-the-database-tablesschema","htmlText":"Migrations: Creating the Database Tables/Schema"},{"level":3,"text":"Migrations \u0026 Adding more Fields","anchor":"migrations--adding-more-fields","htmlText":"Migrations \u0026amp; Adding more Fields"},{"level":3,"text":"Persisting Objects to the Database","anchor":"persisting-objects-to-the-database","htmlText":"Persisting Objects to the Database"},{"level":3,"text":"Validating Objects","anchor":"validating-objects","htmlText":"Validating Objects"},{"level":3,"text":"Fetching Objects from the Database","anchor":"fetching-objects-from-the-database","htmlText":"Fetching Objects from the Database"},{"level":3,"text":"Automatically Fetching Objects (ParamConverter)","anchor":"automatically-fetching-objects-paramconverter","htmlText":"Automatically Fetching Objects (ParamConverter)"},{"level":3,"text":"Updating an Object","anchor":"updating-an-object","htmlText":"Updating an Object"},{"level":3,"text":"Deleting an Object","anchor":"deleting-an-object","htmlText":"Deleting an Object"},{"level":3,"text":"Querying for Objects: The Repository","anchor":"querying-for-objects-the-repository","htmlText":"Querying for Objects: The Repository"},{"level":3,"text":"Querying with DQL or SQL","anchor":"querying-with-dql-or-sql","htmlText":"Querying with DQL or SQL"},{"level":3,"text":"Configuration","anchor":"configuration","htmlText":"Configuration"},{"level":3,"text":"Relationships and Associations","anchor":"relationships-and-associations","htmlText":"Relationships and Associations"},{"level":3,"text":"Dummy Data Fixtures","anchor":"dummy-data-fixtures","htmlText":"Dummy Data Fixtures"},{"level":3,"text":"Learn more","anchor":"learn-more","htmlText":"Learn more"}],"lineInfo":{"truncatedLoc":"881","truncatedSloc":"626"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"issueTemplate":null,"discussionTemplate":null,"language":"reStructuredText","languageID":419,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/dunglas/symfony-docs/blob/f7b26a0d06aa6edb1aae777d74374042ef200216/doctrine.rst","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/dunglas/symfony-docs/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/dunglas/symfony-docs/raw/f7b26a0d06aa6edb1aae777d74374042ef200216/doctrine.rst","renderImageOrRaw":false,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cpre\u003e.. index::\n single: Doctrine\n\n\u003c/pre\u003e\n\u003ca name=\"user-content-databases-and-the-doctrine-orm\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDatabases and the Doctrine ORM\u003c/h2\u003e\u003ca id=\"user-content-databases-and-the-doctrine-orm\" class=\"anchor\" aria-label=\"Permalink: Databases and the Doctrine ORM\" href=\"#databases-and-the-doctrine-orm\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eScreencast\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDo you prefer video tutorials? Check out the \u003ca href=\"https://symfonycasts.com/screencast/symfony-doctrine\" rel=\"nofollow\"\u003eDoctrine screencast series\u003c/a\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSymfony doesn't provide a component to work with the database, but it \u003cem\u003edoes\u003c/em\u003e provide\ntight integration with a third-party library called \u003ca href=\"http://www.doctrine-project.org/\" rel=\"nofollow\"\u003eDoctrine\u003c/a\u003e.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eNote\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis article is all about using the Doctrine ORM. If you prefer to use raw\ndatabase queries, see the \"\u003ca href=\"#id1\"\u003e\u003cspan id=\"user-content-id2\"\u003e:doc:`/doctrine/dbal`\u003c/span\u003e\u003c/a\u003e\" article instead.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eYou can also persist data to \u003ca href=\"https://www.mongodb.org/\" rel=\"nofollow\"\u003eMongoDB\u003c/a\u003e using Doctrine ODM library. See the\n\"\u003ca href=\"https://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html\" rel=\"nofollow\"\u003eDoctrineMongoDBBundle\u003c/a\u003e\" documentation.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-installing-doctrine\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eInstalling Doctrine\u003c/h3\u003e\u003ca id=\"user-content-installing-doctrine\" class=\"anchor\" aria-label=\"Permalink: Installing Doctrine\" href=\"#installing-doctrine\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFirst, install Doctrine support via the ORM pack, as well as the MakerBundle,\nwhich will help generate some code:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ composer require symfony/orm-pack\n$ composer require symfony/maker-bundle --dev\n\u003c/pre\u003e\n\u003ca name=\"user-content-configuring-the-database\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConfiguring the Database\u003c/h4\u003e\u003ca id=\"user-content-configuring-the-database\" class=\"anchor\" aria-label=\"Permalink: Configuring the Database\" href=\"#configuring-the-database\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe database connection information is stored as an environment variable called\n\u003ccode\u003eDATABASE_URL\u003c/code\u003e. For development, you can find and customize this inside \u003ccode\u003e.env\u003c/code\u003e:\u003c/p\u003e\n\u003cpre lang=\"text\"\u003e# .env (or override DATABASE_URL in .env.local to avoid committing your changes)\n\n# customize this line!\nDATABASE_URL=\"mysql://db_user:db_password@127.0.0.1:3306/db_name\"\n\n# to use sqlite:\n# DATABASE_URL=\"sqlite:///%kernel.project_dir%/var/app.db\"\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eCaution!\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf the username, password, host or database name contain any character considered\nspecial in a URI (such as \u003ccode\u003e+\u003c/code\u003e, \u003ccode\u003e@\u003c/code\u003e, \u003ccode\u003e$\u003c/code\u003e, \u003ccode\u003e#\u003c/code\u003e, \u003ccode\u003e/\u003c/code\u003e, \u003ccode\u003e:\u003c/code\u003e, \u003ccode\u003e*\u003c/code\u003e, \u003ccode\u003e!\u003c/code\u003e),\nyou must encode them. See \u003ca href=\"https://www.ietf.org/rfc/rfc3986.txt\" rel=\"nofollow\"\u003eRFC 3986\u003c/a\u003e for the full list of reserved characters or\nuse the \u003ca href=\"#id3\"\u003e\u003cspan id=\"user-content-id4\"\u003e:phpfunction:`urlencode`\u003c/span\u003e\u003c/a\u003e function to encode them. In this case you need to\nremove the \u003ccode\u003eresolve:\u003c/code\u003e prefix in \u003ccode\u003econfig/packages/doctrine.yaml\u003c/code\u003e to avoid errors:\n\u003ccode\u003eurl: '%env(resolve:DATABASE_URL)%'\u003c/code\u003e\u003c/p\u003e\n\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNow that your connection parameters are setup, Doctrine can create the \u003ccode\u003edb_name\u003c/code\u003e\ndatabase for you:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console doctrine:database:create\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThere are more options in \u003ccode\u003econfig/packages/doctrine.yaml\u003c/code\u003e that you can configure,\nincluding your \u003ccode\u003eserver_version\u003c/code\u003e (e.g. 5.7 if you're using MySQL 5.7), which may\naffect how Doctrine functions.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThere are many other Doctrine commands. Run \u003ccode\u003ephp bin/console list doctrine\u003c/code\u003e\nto see a full list.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-creating-an-entity-class\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eCreating an Entity Class\u003c/h3\u003e\u003ca id=\"user-content-creating-an-entity-class\" class=\"anchor\" aria-label=\"Permalink: Creating an Entity Class\" href=\"#creating-an-entity-class\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSuppose you're building an application where products need to be displayed.\nWithout even thinking about Doctrine or databases, you already know that\nyou need a \u003ccode\u003eProduct\u003c/code\u003e object to represent those products.\u003c/p\u003e\n\u003cp id=\"user-content-doctrine-adding-mapping\" dir=\"auto\"\u003eYou can use the \u003ccode\u003emake:entity\u003c/code\u003e command to create this class and any fields you\nneed. The command will ask you some questions - answer them like done below:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:entity\n\nClass name of the entity to create or update:\n\u0026gt; Product\n\nNew property name (press \u0026lt;return\u0026gt; to stop adding fields):\n\u0026gt; name\n\nField type (enter ? to see all types) [string]:\n\u0026gt; string\n\nField length [255]:\n\u0026gt; 255\n\nCan this field be null in the database (nullable) (yes/no) [no]:\n\u0026gt; no\n\nNew property name (press \u0026lt;return\u0026gt; to stop adding fields):\n\u0026gt; price\n\nField type (enter ? to see all types) [string]:\n\u0026gt; integer\n\nCan this field be null in the database (nullable) (yes/no) [no]:\n\u0026gt; no\n\nNew property name (press \u0026lt;return\u0026gt; to stop adding fields):\n\u0026gt;\n(press enter again to finish)\n\u003c/pre\u003e\n\u003cpre\u003e.. versionadded:: 1.3\n The interactive behavior of the ``make:entity`` command was introduced\n in MakerBundle 1.3.\n\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eWoh! You now have a new \u003ccode\u003esrc/Entity/Product.php\u003c/code\u003e file:\u003c/p\u003e\n\u003cpre\u003e// src/Entity/Product.php\nnamespace App\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\n\n/**\n * @ORM\\Entity(repositoryClass=\"App\\Repository\\ProductRepository\")\n */\nclass Product\n{\n /**\n * @ORM\\Id\n * @ORM\\GeneratedValue\n * @ORM\\Column(type=\"integer\")\n */\n private $id;\n\n /**\n * @ORM\\Column(type=\"string\", length=255)\n */\n private $name;\n\n /**\n * @ORM\\Column(type=\"integer\")\n */\n private $price;\n\n public function getId()\n {\n return $this-\u0026gt;id;\n }\n\n // ... getter and setter methods\n}\n\u003c/pre\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eNote\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eConfused why the price is an integer? Don't worry: this is just an example.\nBut, storing prices as integers (e.g. 100 = $1 USD) can avoid rounding issues.\u003c/p\u003e\n\u003c/div\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eCaution!\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThere is a \u003ca href=\"https://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html\" rel=\"nofollow\"\u003elimit of 767 bytes for the index key prefix\u003c/a\u003e when using\nInnoDB tables in MySQL 5.6 and earlier versions. String columns with 255\ncharacter length and \u003ccode\u003eutf8mb4\u003c/code\u003e encoding surpass that limit. This means\nthat any column of type \u003ccode\u003estring\u003c/code\u003e and \u003ccode\u003eunique=true\u003c/code\u003e must set its\nmaximum \u003ccode\u003elength\u003c/code\u003e to \u003ccode\u003e190\u003c/code\u003e. Otherwise, you'll see this error:\n\u003cem\u003e\"[PDOException] SQLSTATE[42000]: Syntax error or access violation:\n1071 Specified key was too long; max key length is 767 bytes\"\u003c/em\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThis class is called an \"entity\". And soon, you'll be able to save and query Product\nobjects to a \u003ccode\u003eproduct\u003c/code\u003e table in your database. Each property in the \u003ccode\u003eProduct\u003c/code\u003e\nentity can be mapped to a column in that table. This is usually done with annotations:\nthe \u003ccode\u003e@ORM\\...\u003c/code\u003e comments that you see above each property:\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"/dunglas/symfony-docs/blob/f7b26a0d06aa6edb1aae777d74374042ef200216/_images/doctrine/mapping_single_entity.png\"\u003e\u003cimg alt=\"/_images/doctrine/mapping_single_entity.png\" src=\"/dunglas/symfony-docs/raw/f7b26a0d06aa6edb1aae777d74374042ef200216/_images/doctrine/mapping_single_entity.png\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003emake:entity\u003c/code\u003e command is a tool to make life easier. But this is \u003cem\u003eyour\u003c/em\u003e code:\nadd/remove fields, add/remove methods or update configuration.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDoctrine supports a wide variety of field types, each with their own options.\nTo see a full list, check out \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html\" rel=\"nofollow\"\u003eDoctrine's Mapping Types documentation\u003c/a\u003e.\nIf you want to use XML instead of annotations, add \u003ccode\u003etype: xml\u003c/code\u003e and\n\u003ccode\u003edir: '%kernel.project_dir%/config/doctrine'\u003c/code\u003e to the entity mappings in your\n\u003ccode\u003econfig/packages/doctrine.yaml\u003c/code\u003e file.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eCaution!\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBe careful not to use reserved SQL keywords as your table or column names\n(e.g. \u003ccode\u003eGROUP\u003c/code\u003e or \u003ccode\u003eUSER\u003c/code\u003e). See Doctrine's \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words\" rel=\"nofollow\"\u003eReserved SQL keywords documentation\u003c/a\u003e\nfor details on how to escape these. Or, change the table name with\n\u003ccode\u003e@ORM\\Table(name=\"groups\")\u003c/code\u003e above the class or configure the column name with\nthe \u003ccode\u003ename=\"group_name\"\u003c/code\u003e option.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-migrations-creating-the-database-tables-schema\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMigrations: Creating the Database Tables/Schema\u003c/h3\u003e\u003ca id=\"user-content-migrations-creating-the-database-tablesschema\" class=\"anchor\" aria-label=\"Permalink: Migrations: Creating the Database Tables/Schema\" href=\"#migrations-creating-the-database-tablesschema\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eProduct\u003c/code\u003e class is fully-configured and ready to save to a \u003ccode\u003eproduct\u003c/code\u003e table.\nIf you just defined this class, your database doesn't actually have the \u003ccode\u003eproduct\u003c/code\u003e\ntable yet. To add it, you can leverage the \u003ca href=\"https://github.com/doctrine/DoctrineMigrationsBundle\"\u003eDoctrineMigrationsBundle\u003c/a\u003e, which is\nalready installed:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:migration\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf everything worked, you should see something like this:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eSUCCESS!\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eNext: Review the new migration \"src/Migrations/Version20180207231217.php\"\nThen: Run the migration with php bin/console doctrine:migrations:migrate\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eIf you open this file, it contains the SQL needed to update your database! To run\nthat SQL, execute your migrations:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console doctrine:migrations:migrate\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThis command executes all migration files that have not already been run against\nyour database. You should run this command on production when you deploy to keep\nyour production database up-to-date.\u003c/p\u003e\n\u003ca name=\"user-content-migrations-adding-more-fields\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eMigrations \u0026amp; Adding more Fields\u003c/h3\u003e\u003ca id=\"user-content-migrations--adding-more-fields\" class=\"anchor\" aria-label=\"Permalink: Migrations \u0026amp; Adding more Fields\" href=\"#migrations--adding-more-fields\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eBut what if you need to add a new field property to \u003ccode\u003eProduct\u003c/code\u003e, like a \u003ccode\u003edescription\u003c/code\u003e?\nYou can edit the class to add the new property. But, you can also use \u003ccode\u003emake:entity\u003c/code\u003e\nagain:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:entity\n\nClass name of the entity to create or update\n\u0026gt; Product\n\nNew property name (press \u0026lt;return\u0026gt; to stop adding fields):\n\u0026gt; description\n\nField type (enter ? to see all types) [string]:\n\u0026gt; text\n\nCan this field be null in the database (nullable) (yes/no) [no]:\n\u0026gt; no\n\nNew property name (press \u0026lt;return\u0026gt; to stop adding fields):\n\u0026gt;\n(press enter again to finish)\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThis adds the new \u003ccode\u003edescription\u003c/code\u003e property and \u003ccode\u003egetDescription()\u003c/code\u003e and \u003ccode\u003esetDescription()\u003c/code\u003e\nmethods:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-diff notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// src/Entity/Product.php\n// ...\n\nclass Product\n{\n // ...\n\n+ /**\n+ * @ORM\\Column(type=\u0026quot;text\u0026quot;)\n+ */\n+ private $description;\n\n // getDescription() \u0026amp; setDescription() were also added\n}\"\u003e\u003cpre\u003e// src/Entity/Product.php\n// ...\n\nclass Product\n{\n // ...\n\n\u003cspan class=\"pl-mi1\"\u003e\u003cspan class=\"pl-mi1\"\u003e+\u003c/span\u003e /**\u003c/span\u003e\n\u003cspan class=\"pl-mi1\"\u003e\u003cspan class=\"pl-mi1\"\u003e+\u003c/span\u003e * @ORM\\Column(type=\"text\")\u003c/span\u003e\n\u003cspan class=\"pl-mi1\"\u003e\u003cspan class=\"pl-mi1\"\u003e+\u003c/span\u003e */\u003c/span\u003e\n\u003cspan class=\"pl-mi1\"\u003e\u003cspan class=\"pl-mi1\"\u003e+\u003c/span\u003e private $description;\u003c/span\u003e\n\n // getDescription() \u0026amp; setDescription() were also added\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe new property is mapped, but it doesn't exist yet in the \u003ccode\u003eproduct\u003c/code\u003e table. No\nproblem! Generate a new migration:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:migration\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThis time, the SQL in the generated file will look like this:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-sql notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"ALTER TABLE product ADD description LONGTEXT NOT NULL\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003eALTER\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eTABLE\u003c/span\u003e product ADD description LONGTEXT \u003cspan class=\"pl-k\"\u003eNOT NULL\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe migration system is \u003cem\u003esmart\u003c/em\u003e. It compares all of your entities with the current\nstate of the database and generates the SQL needed to synchronize them! Like\nbefore, execute your migrations:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console doctrine:migrations:migrate\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThis will only execute the \u003cem\u003eone\u003c/em\u003e new migration file, because DoctrineMigrationsBundle\nknows that the first migration was already executed earlier. Behind the scenes, it\nmanages a \u003ccode\u003emigration_versions\u003c/code\u003e table to track this.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eEach time you make a change to your schema, run these two commands to generate the\nmigration and then execute it. Be sure to commit the migration files and execute\nthem when you deploy.\u003c/p\u003e\n\u003cdiv id=\"user-content-doctrine-generating-getters-and-setters\" dir=\"auto\"\u003
8000
e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf you prefer to add new properties manually, the \u003ccode\u003emake:entity\u003c/code\u003e command can\ngenerate the getter \u0026amp; setter methods for you:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:entity --regenerate\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf you make some changes and want to regenerate \u003cem\u003eall\u003c/em\u003e getter/setter methods,\nalso pass \u003ccode\u003e--overwrite\u003c/code\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-persisting-objects-to-the-database\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePersisting Objects to the Database\u003c/h3\u003e\u003ca id=\"user-content-persisting-objects-to-the-database\" class=\"anchor\" aria-label=\"Permalink: Persisting Objects to the Database\" href=\"#persisting-objects-to-the-database\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIt's time to save a \u003ccode\u003eProduct\u003c/code\u003e object to the database! Let's create a new controller\nto experiment:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:controller ProductController\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eInside the controller, you can create a new \u003ccode\u003eProduct\u003c/code\u003e object, set data on it,\nand save it!\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-text-html-php notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// src/Controller/ProductController.php\nnamespace App\\Controller;\n\n// ...\nuse Symfony\\Component\\HttpFoundation\\Response;\n\nuse App\\Entity\\Product;\n\nclass ProductController extends AbstractController\n{\n /**\n * @Route(\u0026quot;/product\u0026quot;, name=\u0026quot;product\u0026quot;)\n */\n public function index()\n {\n // you can fetch the EntityManager via $this-\u0026gt;getDoctrine()\n // or you can add an argument to your action: index(EntityManagerInterface $entityManager)\n $entityManager = $this-\u0026gt;getDoctrine()-\u0026gt;getManager();\n\n $product = new Product();\n $product-\u0026gt;setName('Keyboard');\n $product-\u0026gt;setPrice(1999);\n $product-\u0026gt;setDescription('Ergonomic and stylish!');\n\n // tell Doctrine you want to (eventually) save the Product (no queries yet)\n $entityManager-\u0026gt;persist($product);\n\n // actually executes the queries (i.e. the INSERT query)\n $entityManager-\u0026gt;flush();\n\n return new Response('Saved new product with id '.$product-\u0026gt;getId());\n }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e// src/Controller/ProductController.php\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003enamespace\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApp\u003c/span\u003e\\\u003cspan class=\"pl-v\"\u003eController\u003c/span\u003e;\n\n\u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eSymfony\u003c/span\u003e\\\u003cspan class=\"pl-v\"\u003eComponent\u003c/span\u003e\\\u003cspan class=\"pl-v\"\u003eHttpFoundation\u003c/span\u003e\\\u003cspan class=\"pl-smi\"\u003eResponse\u003c/span\u003e;\n\n\u003cspan class=\"pl-k\"\u003euse\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eApp\u003c/span\u003e\\\u003cspan class=\"pl-v\"\u003eEntity\u003c/span\u003e\\\u003cspan class=\"pl-smi\"\u003eProduct\u003c/span\u003e;\n\n\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e ProductController \u003cspan class=\"pl-k\"\u003eextends\u003c/span\u003e AbstractController\n{\n \u003cspan class=\"pl-c\"\u003e/**\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e * @Route(\"/product\", name=\"product\")\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e */\u003c/span\u003e\n \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-k\"\u003efunction\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eindex\u003c/span\u003e()\n {\n \u003cspan class=\"pl-c\"\u003e// you can fetch the EntityManager via $this-\u0026gt;getDoctrine()\u003c/span\u003e\n \u003cspan class=\"pl-c\"\u003e// or you can add an argument to your action: index(EntityManagerInterface $entityManager)\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eentityManager\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003e\u003cspan class=\"pl-smi\"\u003ethis\u003c/span\u003e\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003egetDoctrine\u003c/span\u003e()-\u0026gt;\u003cspan class=\"pl-en\"\u003egetManager\u003c/span\u003e();\n\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eproduct\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eProduct\u003c/span\u003e();\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eproduct\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003esetName\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e'\u003cspan class=\"pl-s\"\u003eKeyboard\u003c/span\u003e'\u003c/span\u003e);\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eproduct\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003esetPrice\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e1999\u003c/span\u003e);\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eproduct\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003esetDescription\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e'\u003cspan class=\"pl-s\"\u003eErgonomic and stylish!\u003c/span\u003e'\u003c/span\u003e);\n\n \u003cspan class=\"pl-c\"\u003e// tell Doctrine you want to (eventually) save the Product (no queries yet)\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eentityManager\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003epersist\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eproduct\u003c/span\u003e);\n\n \u003cspan class=\"pl-c\"\u003e// actually executes the queries (i.e. the INSERT query)\u003c/span\u003e\n \u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eentityManager\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003eflush\u003c/span\u003e();\n\n \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-v\"\u003eResponse\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e'\u003cspan class=\"pl-s\"\u003eSaved new product with id \u003c/span\u003e'\u003c/span\u003e.\u003cspan class=\"pl-s1\"\u003e\u003cspan class=\"pl-c1\"\u003e$\u003c/span\u003eproduct\u003c/span\u003e-\u0026gt;\u003cspan class=\"pl-en\"\u003egetId\u003c/span\u003e());\n }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTry it out!\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ca href=\"http://localhost:8000/product\" rel=\"nofollow\"\u003ehttp://localhost:8000/product\u003c/a\u003e\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eCongratulations! You just created your first row in the \u003ccode\u003eproduct\u003c/code\u003e table. To prove it,\nyou can query the database directly:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console doctrine:query:sql 'SELECT * FROM product'\n\n# on Windows systems not using Powershell, run this command instead:\n# php bin/console doctrine:query:sql \"SELECT * FROM product\"\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eTake a look at the previous example in more detail:\u003c/p\u003e\n\u003cul id=\"user-content-doctrine-entity-manager\" dir=\"auto\"\u003e\n\u003cli\u003e\u003cstrong\u003eline 18\u003c/strong\u003e The \u003ccode\u003e$this-\u0026gt;getDoctrine()-\u0026gt;getManager()\u003c/code\u003e method gets Doctrine's\n\u003cem\u003eentity manager\u003c/em\u003e object, which is the most important object in Doctrine. It's\nresponsible for saving objects to, and fetching objects from, the database.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003elines 20-23\u003c/strong\u003e In this section, you instantiate and work with the \u003ccode\u003e$product\u003c/code\u003e\nobject like any other normal PHP object.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eline 26\u003c/strong\u003e The \u003ccode\u003epersist($product)\u003c/code\u003e call tells Doctrine to \"manage\" the\n\u003ccode\u003e$product\u003c/code\u003e object. This does \u003cstrong\u003enot\u003c/strong\u003e cause a query to be made to the database.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eline 29\u003c/strong\u003e When the \u003ccode\u003eflush()\u003c/code\u003e method is called, Doctrine looks through\nall of the objects that it's managing to see if they need to be persisted\nto the database. In this example, the \u003ccode\u003e$product\u003c/code\u003e object's data doesn't\nexist in the database, so the entity manager executes an \u003ccode\u003eINSERT\u003c/code\u003e query,\ncreating a new row in the \u003ccode\u003eproduct\u003c/code\u003e table.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eNote\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIf the \u003ccode\u003eflush()\u003c/code\u003e call fails, a \u003ccode\u003eDoctrine\\ORM\\ORMException\u003c/code\u003e exception\nis thrown. See \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/transactions-and-concurrency.html\" rel=\"nofollow\"\u003eTransactions and Concurrency\u003c/a\u003e.\u003c/p\u003e\n\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhether you're creating or updating objects, the workflow is always the same: Doctrine\nis smart enough to know if it should INSERT or UPDATE your entity.\u003c/p\u003e\n\u003ca name=\"user-content-validating-objects\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eValidating Objects\u003c/h3\u003e\u003ca id=\"user-content-validating-objects\" class=\"anchor\" aria-label=\"Permalink: Validating Objects\" href=\"#validating-objects\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"#id5\"\u003e\u003cspan id=\"user-content-id6\"\u003e:doc:`The Symfony validator \u0026lt;/validation\u0026gt;`\u003c/span\u003e\u003c/a\u003e reuses Doctrine metadata\nto perform some basic validation tasks:\u003c/p\u003e\n\u003cpre\u003e// src/Controller/ProductController.php\nnamespace App\\Controller;\n\n// ...\nuse Symfony\\Component\\HttpFoundation\\Response;\nuse Symfony\\Component\\Validator\\Validator\\ValidatorInterface;\n\nuse App\\Entity\\Product;\n\nclass ProductController extends AbstractController\n{\n /**\n * @Route(\"/product\", name=\"product\")\n */\n public function index(ValidatorInterface $validator)\n {\n $product = new Product();\n $product-\u0026gt;setName(null); // The column in database isn't nullable\n $product-\u0026gt;setPrice('1999'); // Type mismatch, an integer is expected\n\n // ...\n\n $errors = $validator-\u0026gt;validate($product);\n if (count($errors) \u0026gt; 0) {\n return new Response((string) $errors, 400);\n }\n\n // Will not be reached in this example\n $entityManager = $this-\u0026gt;getDoctrine()-\u0026gt;getManager();\n $entityManager-\u0026gt;persist($product);\n $entityManager-\u0026gt;flush();\n\n return new Response('Saved new product with id '.$product-\u0026gt;getId());\n }\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThe following table summarizes the mapping between Doctrine metadata and\nthe corresponding validation constraints:\u003c/p\u003e\n\u003cmarkdown-accessiblity-table\u003e\u003ctable\u003e\n\n\n\n\n\n\u003cthead valign=\"bottom\"\u003e\n\u003ctr\u003e\u003cth\u003eDoctrine attribute\u003c/th\u003e\n\u003cth\u003eValidation constraint\u003c/th\u003e\n\u003cth\u003eNotes\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody valign=\"top\"\u003e\n\u003ctr\u003e\u003ctd\u003e\u003ccode\u003enullable=true\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"#id7\"\u003e\u003cspan id=\"user-content-id8\"\u003e:doc:`NotNull \u0026lt;/reference/constraints/NotNull\u0026gt;`\u003c/span\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003eRelies on \u003ca href=\"#id9\"\u003e\u003cspan id=\"user-content-id10\"\u003e:doc:`the PropertyInfo component \u0026lt;/components/property_info\u0026gt;`\u003c/span\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003ccode\u003etype\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"#id11\"\u003e\u003cspan id=\"user-content-id12\"\u003e:doc:`Type \u0026lt;/reference/constraints/Type\u0026gt;`\u003c/span\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003eRelies on \u003ca href=\"#id13\"\u003e\u003cspan id=\"user-content-id14\"\u003e:doc:`the PropertyInfo component \u0026lt;/components/property_info\u0026gt;`\u003c/span\u003e\u003c/a\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003ccode\u003eunique=true\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"#id15\"\u003e\u003cspan id=\"user-content-id16\"\u003e:doc:`UniqueEntity \u0026lt;/reference/constraints/UniqueEntity\u0026gt;`\u003c/span\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e \u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003ccode\u003elength\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003e\u003ca href=\"#id17\"\u003e\u003cspan id=\"user-content-id18\"\u003e:doc:`Length \u0026lt;/reference/constraints/Length\u0026gt;`\u003c/span\u003e\u003c/a\u003e\u003c/td\u003e\n\u003ctd\u003e \u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\u003c/markdown-accessiblity-table\u003e\n\u003cp dir=\"auto\"\u003eBecause \u003ca href=\"#id19\"\u003e\u003cspan id=\"user-content-id20\"\u003e:doc:`the Form component \u0026lt;/forms\u0026gt;`\u003c/span\u003e\u003c/a\u003e as well as \u003ca href=\"https://api-platform.com/docs/core/validation/\" rel=\"nofollow\"\u003eAPI Platform\u003c/a\u003e\ninternally use the Validator Component, all your forms\nand web APIs will also automatically benefit from these default constraints.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eDon't forget to add \u003ca href=\"#id21\"\u003e\u003cspan id=\"user-content-id22\"\u003e:doc:`more precise validation constraints \u0026lt;/reference/constraints\u0026gt;`\u003c/span\u003e\u003c/a\u003e\nto ensure that data provided by the user is correct.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-fetching-objects-from-the-database\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFetching Objects from the Database\u003c/h3\u003e\u003ca id=\"user-content-fetching-objects-from-the-database\" class=\"anchor\" aria-label=\"Permalink: Fetching Objects from the Database\" href=\"#fetching-objects-from-the-database\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFetching an object back out of the database is even easier. Suppose you want to\nbe able to go to \u003ccode\u003e/product/1\u003c/code\u003e to see your new product:\u003c/p\u003e\n\u003cpre\u003e// src/Controller/ProductController.php\n// ...\n\n/**\n * @Route(\"/product/{id}\", name=\"product_show\")\n */\npublic function show($id)\n{\n $product = $this-\u0026gt;getDoctrine()\n -\u0026gt;getRepository(Product::class)\n -\u0026gt;find($id);\n\n if (!$product) {\n throw $this-\u0026gt;createNotFoundException(\n 'No product found for id '.$id\n );\n }\n\n return new Response('Check out this great product: '.$product-\u0026gt;getName());\n\n // or render a template\n // in the template, print things with {{ product.name }}\n // return $this-\u0026gt;render('product/show.html.twig', ['product' =\u0026gt; $product]);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eTry it out!\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ca href=\"http://localhost:8000/product/1\" rel=\"nofollow\"\u003ehttp://localhost:8000/product/1\u003c/a\u003e\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eWhen you query for a particular type of object, you always use what's known\nas its \"repository\". You can think of a repository as a PHP class whose only\njob is to help you fetch entities of a certain class.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eOnce you have a repository object, you have many helper methods:\u003c/p\u003e\n\u003cpre\u003e$repository = $this-\u0026gt;getDoctrine()-\u0026gt;getRepository(Product::class);\n\n// look for a single Product by its primary key (usually \"id\")\n$product = $repository-\u0026gt;find($id);\n\n// look for a single Product by name\n$product = $repository-\u0026gt;findOneBy(['name' =\u0026gt; 'Keyboard']);\n// or find by name and price\n$product = $repository-\u0026gt;findOneBy([\n 'name' =\u0026gt; 'Keyboard',\n 'price' =\u0026gt; 1999,\n]);\n\n// look for multiple Product objects matching the name, ordered by price\n$products = $repository-\u0026gt;findBy(\n ['name' =\u0026gt; 'Keyboard'],\n ['price' =\u0026gt; 'ASC']\n);\n\n// look for *all* Product objects\n$products = $repository-\u0026gt;findAll();\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eYou can also add \u003cem\u003ecustom\u003c/em\u003e methods for more complex queries! More on that later in\nthe \u003ca href=\"#id23\"\u003e\u003cspan id=\"user-content-id24\"\u003e:ref:`doctrine-queries`\u003c/span\u003e\u003c/a\u003e section.\u003c/p\u003e\n\u003cdiv dir=\"auto\"\u003e\n\u003cp dir=\"auto\"\u003eTip\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eWhen rendering an HTML page, the web debug toolbar at the bottom of the page\nwill display the number of queries and the time it took to execute them:\u003c/p\u003e\n\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"/dunglas/symfony-docs/blob/f7b26a0d06aa6edb1aae777d74374042ef200216/_images/doctrine/doctrine_web_debug_toolbar.png\"\u003e\u003cimg alt=\"/_images/doctrine/doctrine_web_debug_toolbar.png\" src=\"/dunglas/symfony-docs/raw/f7b26a0d06aa6edb1aae777d74374042ef200216/_images/doctrine/doctrine_web_debug_toolbar.png\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\n\u003cp dir=\"auto\"\u003eIf the number of database queries is too high, the icon will turn yellow to\nindicate that something may not be correct. Click on the icon to open the\nSymfony Profiler and see the exact queries that were executed. If you don't\nsee the web debug toolbar, try running \u003ccode\u003ecomposer require --dev symfony/profiler-pack\u003c/code\u003e\nto install it.\u003c/p\u003e\n\u003c/div\u003e\n\u003ca name=\"user-content-automatically-fetching-objects-paramconverter\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAutomatically Fetching Objects (ParamConverter)\u003c/h3\u003e\u003ca id=\"user-content-automatically-fetching-objects-paramconverter\" class=\"anchor\" aria-label=\"Permalink: Automatically Fetching Objects (ParamConverter)\" href=\"#automatically-fetching-objects-paramconverter\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn many cases, you can use the \u003ca href=\"http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html\" rel=\"nofollow\"\u003eSensioFrameworkExtraBundle\u003c/a\u003e to do the query\nfor you automatically! First, install the bundle in case you don't have it:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ composer require sensio/framework-extra-bundle\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eNow, simplify your controller:\u003c/p\u003e\n\u003cpre\u003e// src/Controller/ProductController.php\n\nuse App\\Entity\\Product;\n// ...\n\n/**\n * @Route(\"/product/{id}\", name=\"product_show\")\n */\npublic function show(Product $product)\n{\n // use the Product!\n // ...\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThat's it! The bundle uses the \u003ccode\u003e{id}\u003c/code\u003e from the route to query for the \u003ccode\u003eProduct\u003c/code\u003e\nby the \u003ccode\u003eid\u003c/code\u003e column. If it's not found, a 404 page is generated.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThere are many more options you can use. Read more about the \u003ca href=\"http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html\" rel=\"nofollow\"\u003eParamConverter\u003c/a\u003e.\u003c/p\u003e\n\u003ca name=\"user-content-updating-an-object\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUpdating an Object\u003c/h3\u003e\u003ca id=\"user-content-updating-an-object\" class=\"anchor\" aria-label=\"Permalink: Updating an Object\" href=\"#updating-an-object\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOnce you've fetched an object from Doctrine, you interact with it the same as\nwith any PHP model:\u003c/p\u003e\n\u003cpre\u003e/**\n * @Route(\"/product/edit/{id}\")\n */\npublic function update($id)\n{\n $entityManager = $this-\u0026gt;getDoctrine()-\u0026gt;getManager();\n $product = $entityManager-\u0026gt;getRepository(Product::class)-\u0026gt;find($id);\n\n if (!$product) {\n throw $this-\u0026gt;createNotFoundException(\n 'No product found for id '.$id\n );\n }\n\n $product-\u0026gt;setName('New product name!');\n $entityManager-\u0026gt;flush();\n\n return $this-\u0026gt;redirectToRoute('product_show', [\n 'id' =\u0026gt; $product-\u0026gt;getId()\n ]);\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eUsing Doctrine to edit an existing product consists of three steps:\u003c/p\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003efetching the object from Doctrine;\u003c/li\u003e\n\u003cli\u003emodifying the object;\u003c/li\u003e\n\u003cli\u003ecalling \u003ccode\u003eflush()\u003c/code\u003e on the entity manager.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp dir=\"auto\"\u003eYou \u003cem\u003ecan\u003c/em\u003e call \u003ccode\u003e$entityManager-\u0026gt;persist($product)\u003c/code\u003e, but it isn't necessary:\nDoctrine is already \"watching\" your object for changes.\u003c/p\u003e\n\u003ca name=\"user-content-deleting-an-object\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDeleting an Object\u003c/h3\u003e\u003ca id=\"user-content-deleting-an-object\" class=\"anchor\" aria-label=\"Permalink: Deleting an Object\" href=\"#deleting-an-object\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eDeleting an object is very similar, but requires a call to the \u003ccode\u003eremove()\u003c/code\u003e\nmethod of the entity manager:\u003c/p\u003e\n\u003cpre\u003e$entityManager-\u0026gt;remove($product);\n$entityManager-\u0026gt;flush();\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eAs you might expect, the \u003ccode\u003eremove()\u003c/code\u003e method notifies Doctrine that you'd\nlike to remove the given object from the database. The \u003ccode\u003eDELETE\u003c/code\u003e query isn't\nactually executed until the \u003ccode\u003eflush()\u003c/code\u003e method is called.\u003c/p\u003e\n\u003ca name=\"user-content-querying-for-objects-the-repository\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eQuerying for Objects: The Repository\u003c/h3\u003e\u003ca id=\"user-content-querying-for-objects-the-repository\" class=\"anchor\" aria-label=\"Permalink: Querying for Objects: The Repository\" href=\"#querying-for-objects-the-repository\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eYou've already seen how the repository object allows you to run basic queries\nwithout any work:\u003c/p\u003e\n\u003cpre\u003e// from inside a controller\n$repository = $this-\u0026gt;getDoctrine()-\u0026gt;getRepository(Product::class);\n\n$product = $repository-\u0026gt;find($id);\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eBut what if you need a more complex query? When you generated your entity with\n\u003ccode\u003emake:entity\u003c/code\u003e, the command \u003cem\u003ealso\u003c/em\u003e generated a \u003ccode\u003eProductRepository\u003c/code\u003e class:\u003c/p\u003e\n\u003cpre\u003e// src/Repository/ProductRepository.php\nnamespace App\\Repository;\n\nuse App\\Entity\\Product;\nuse Doctrine\\Bundle\\DoctrineBundle\\Repository\\ServiceEntityRepository;\nuse Symfony\\Bridge\\Doctrine\\RegistryInterface;\n\nclass ProductRepository extends ServiceEntityRepository\n{\n public function __construct(RegistryInterface $registry)\n {\n parent::__construct($registry, Product::class);\n }\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eWhen you fetch your repository (i.e. \u003ccode\u003e-\u0026gt;getRepository(Product::class)\u003c/code\u003e), it is\n\u003cem\u003eactually\u003c/em\u003e an instance of \u003cem\u003ethis\u003c/em\u003e object! This is because of the \u003ccode\u003erepositoryClass\u003c/code\u003e\nconfig that was generated at the top of your \u003ccode\u003eProduct\u003c/code\u003e entity class.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eSuppose you want to query for all Product objects greater than a certain price. Add\na new method for this to your repository:\u003c/p\u003e\n\u003cpre\u003e// src/Repository/ProductRepository.php\n\n// ...\nclass ProductRepository extends ServiceEntityRepository\n{\n public function __construct(RegistryInterface $registry)\n {\n parent::__construct($registry, Product::class);\n }\n\n /**\n * @param $price\n * @return Product[]\n */\n public function findAllGreaterThanPrice($price): array\n {\n // automatically knows to select Products\n // the \"p\" is an alias you'll use in the rest of the query\n $qb = $this-\u0026gt;createQueryBuilder('p')\n -\u0026gt;andWhere('p.price \u0026gt; :price')\n -\u0026gt;setParameter('price', $price)\n -\u0026gt;orderBy('p.price', 'ASC')\n -\u0026gt;getQuery();\n\n return $qb-\u0026gt;execute();\n\n // to get just one result:\n // $product = $qb-\u0026gt;setMaxResults(1)-\u0026gt;getOneOrNullResult();\n }\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThis uses Doctrine's \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html\" rel=\"nofollow\"\u003eQuery Builder\u003c/a\u003e: a very powerful and user-friendly way to\nwrite custom queries. Now, you can call this method on the repository:\u003c/p\u003e\n\u003cpre\u003e// from inside a controller\n$minPrice = 1000;\n\n$products = $this-\u0026gt;getDoctrine()\n -\u0026gt;getRepository(Product::class)\n -\u0026gt;findAllGreaterThanPrice($minPrice);\n\n// ...\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eIf you're in a \u003ca href=\"#id25\"\u003e\u003cspan id=\"user-content-id26\"\u003e:ref:`services-constructor-injection`\u003c/span\u003e\u003c/a\u003e, you can type-hint the\n\u003ccode\u003eProductRepository
5956
\u003c/code\u003e class and inject it like normal.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor more details, see the \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/query-builder.html\" rel=\"nofollow\"\u003eQuery Builder\u003c/a\u003e Documentation from Doctrine.\u003c/p\u003e\n\u003ca name=\"user-content-querying-with-dql-or-sql\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eQuerying with DQL or SQL\u003c/h3\u003e\u003ca id=\"user-content-querying-with-dql-or-sql\" class=\"anchor\" aria-label=\"Permalink: Querying with DQL or SQL\" href=\"#querying-with-dql-or-sql\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIn addition to the query builder, you can also query with \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html\" rel=\"nofollow\"\u003eDoctrine Query Language\u003c/a\u003e:\u003c/p\u003e\n\u003cpre\u003e// src/Repository/ProductRepository.php\n// ...\n\npublic function findAllGreaterThanPrice($price): array\n{\n $entityManager = $this-\u0026gt;getEntityManager();\n\n $query = $entityManager-\u0026gt;createQuery(\n 'SELECT p\n FROM App\\Entity\\Product p\n WHERE p.price \u0026gt; :price\n ORDER BY p.price ASC'\n )-\u0026gt;setParameter('price', $price);\n\n // returns an array of Product objects\n return $query-\u0026gt;execute();\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eOr directly with SQL if you need to:\u003c/p\u003e\n\u003cpre\u003e// src/Repository/ProductRepository.php\n// ...\n\npublic function findAllGreaterThanPrice($price): array\n{\n $conn = $this-\u0026gt;getEntityManager()-\u0026gt;getConnection();\n\n $sql = '\n SELECT * FROM product p\n WHERE p.price \u0026gt; :price\n ORDER BY p.price ASC\n ';\n $stmt = $conn-\u0026gt;prepare($sql);\n $stmt-\u0026gt;execute(['price' =\u0026gt; $price]);\n\n // returns an array of arrays (i.e. a raw data set)\n return $stmt-\u0026gt;fetchAll();\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eWith SQL, you will get back raw data, not objects (unless you use the \u003ca href=\"http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html\" rel=\"nofollow\"\u003eNativeQuery\u003c/a\u003e\nfunctionality).\u003c/p\u003e\n\u003ca name=\"user-content-configuration\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eConfiguration\u003c/h3\u003e\u003ca id=\"user-content-configuration\" class=\"anchor\" aria-label=\"Permalink: Configuration\" href=\"#configuration\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSee the \u003ca href=\"#id27\"\u003e\u003cspan id=\"user-content-id28\"\u003e:doc:`Doctrine config reference \u0026lt;/reference/configuration/doctrine\u0026gt;`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003ca name=\"user-content-relationships-and-associations\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eRelationships and Associations\u003c/h3\u003e\u003ca id=\"user-content-relationships-and-associations\" class=\"anchor\" aria-label=\"Permalink: Relationships and Associations\" href=\"#relationships-and-associations\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eDoctrine provides all the functionality you need to manage database relationships\n(also known as associations), including ManyToOne, OneToMany, OneToOne and ManyToMany\nrelationships.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor info, see \u003ca href=\"#id29\"\u003e\u003cspan id=\"user-content-id30\"\u003e:doc:`/doctrine/associations`\u003c/span\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003ca name=\"user-content-dummy-data-fixtures\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eDummy Data Fixtures\u003c/h3\u003e\u003ca id=\"user-content-dummy-data-fixtures\" class=\"anchor\" aria-label=\"Permalink: Dummy Data Fixtures\" href=\"#dummy-data-fixtures\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eDoctrine provides a library that allows you to programmatically load testing\ndata into your project (i.e. \"fixture data\"). Install it with:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ composer require doctrine/doctrine-fixtures-bundle --dev\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eThen, use the \u003ccode\u003emake:fixtures\u003c/code\u003e command to generate an empty fixture class:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console make:fixtures\n\nThe class name of the fixtures to create (e.g. AppFixtures):\n\u0026gt; ProductFixture\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eCustomize the new class to load \u003ccode\u003eProduct\u003c/code\u003e objects into Doctrine:\u003c/p\u003e\n\u003cpre\u003e// src/DataFixtures/ProductFixture.php\nnamespace App\\DataFixtures;\n\nuse Doctrine\\Bundle\\FixturesBundle\\Fixture;\nuse Doctrine\\Common\\Persistence\\ObjectManager;\n\nclass ProductFixture extends Fixture\n{\n public function load(ObjectManager $manager)\n {\n $product = new Product();\n $product-\u0026gt;setName('Priceless widget!');\n $product-\u0026gt;setPrice(14.50);\n $product-\u0026gt;setDescription('Ok, I guess it *does* have a price');\n $manager-\u0026gt;persist($product);\n\n // add more products\n\n $manager-\u0026gt;flush();\n }\n}\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eEmpty the database and reload \u003cem\u003eall\u003c/em\u003e the fixture classes with:\u003c/p\u003e\n\u003cpre lang=\"terminal\"\u003e$ php bin/console doctrine:fixtures:load\n\u003c/pre\u003e\n\u003cp dir=\"auto\"\u003eFor information, see the \"\u003ca href=\"https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html\" rel=\"nofollow\"\u003eDoctrineFixturesBundle\u003c/a\u003e\" documentation.\u003c/p\u003e\n\u003ca name=\"user-content-learn-more\"\u003e\u003c/a\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eLearn more\u003c/h3\u003e\u003ca id=\"user-content-learn-more\" class=\"anchor\" aria-label=\"Permalink: Learn more\" href=\"#learn-more\"\u003e\u003csvg class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cpre\u003e.. toctree::\n :maxdepth: 1\n\n doctrine/associations\n doctrine/common_extensions\n doctrine/lifecycle_callbacks\n doctrine/event_listeners_subscribers\n doctrine/registration_form\n doctrine/custom_dql_functions\n doctrine/dbal\n doctrine/multiple_entity_managers\n doctrine/pdo_session_storage\n doctrine/mongodb_session_storage\n doctrine/resolve_target_entity\n doctrine/reverse_engineering\n\n\u003c/pre\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html\" rel=\"nofollow\"\u003eDoctrineFixturesBundle\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\n\u003c/article\u003e","renderedFileInfo":null,"shortPath":null,"symbolsEnabled":true,"tabSize":8,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":"/dunglas/.github/blob/c71869a11b07d839dcb216be54a75e6cbb703699/FUNDING.yml","showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null,"symbols":null},"copilotInfo":null,"copilotAccessAllowed":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true,"csrf_tokens":{"/dunglas/symfony-docs/branches":{"post":"sY_NrrtVKNqzPbao6ssiVBTj1coc9fhXOdAVuLMB2-FkWltcqric_GH9as0al9mg0NJ3fTcMkC-od3jEMcw4MQ"},"/repos/preferences":{"post":"7mBVdHOfm9bg0DQ2t02rY-rU6KzkPE2nDgEtki0Vyy7iyDfsse8l3-K-z44d_DhbnJ7GekLn4xFE-2B3CVRjFA"}}},"title":"symfony-docs/doctrine.rst at f7b26a0d06aa6edb1aae777d74374042ef200216 · dunglas/symfony-docs","appPayload":{"helpUrl":"https://docs.github.com","findFileWorkerPath":"/assets-cdn/worker/find-file-worker-263cab1760dd.js","findInFileWorkerPath":"/assets-cdn/worker/find-in-file-worker-0b6f8702959e.js","githubDevUrl":null,"enabled_features":{"code_nav_ui_events":false,"react_blob_overlay":false,"accessible_code_button":true}}}