Relations

Contents
OneToMany side
ManyToOne side
Cascade persist
Orphan removal note

OneToMany side

A shop author writes many posts, but each post has one author. The parent side holds a collection of children mapped by the field on the child side.

The mappedBy value names that child field, and targetEntity names the child class. Build an empty collection in the constructor so the property is never null.

#[ORM\OneToMany(mappedBy: "author", targetEntity: Post::class)] private Collection $posts; public function __construct() { $this->posts = new ArrayCollection(); }

ManyToOne side

The child side owns the link: it stores the foreign key column in the database. The inversedBy value names the collection on the parent side, so both sides stay in sync.

Join column settings describe the column itself. Marking it not nullable means every post must belong to an author.

#[ORM\ManyToOne(inversedBy: "posts")] #[ORM\JoinColumn(nullable: false)] private Author $author;

Cascade persist

Saving a parent with new children takes one extra word in the mapping: cascade with persist. New children then save together with the parent in one go.

Persist the parent once and flush. Doctrine inserts the parent row first, then the child rows with the right foreign keys.

$entityManager->persist($author); $entityManager->flush();

Orphan removal note

Removing a child from the collection breaks the link, but the row stays in the database by default. That default surprises beginners who expect a delete.

Set orphan removal on the parent mapping when a child without a parent makes no sense. Doctrine then deletes the row once it leaves the collection.

#[ORM\OneToMany(mappedBy: "author", targetEntity: Post::class, orphanRemoval: true)]

Next: Forms

Article author: Arthur Isaev

Related articles
Development with PHP
What is Symfony and where it runs
Install Symfony
Your first page
Routes
Controllers
Twig basics
Twig advanced
Doctrine setup
Entities
Migrations
Repositories
Relations
Forms
Validation
Services and DI
JSON controllers
Serializer
Security intro
Users
Login form
Voters
Console commands
Events
Messenger
Mailer
Cache
Sessions
CSRF
Translations
Dotenv and env
Profiler
Testing
Fixtures
Pagination
File uploads
API Platform in one lesson
DQL
Transactions
Migrations advanced
Security advanced
HTTP client
Scheduler
Webhooks
Asset Mapper
Deployment
Performance
Capstone: blog
Capstone: JSON API
Modern Symfony tour
Hero roadmap: the whole course on one page

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: