Problem
My application is built with Zend Framework 2 and Doctrine 2.
I’m having trouble understanding the difference between mappedBy and inversedBy while writing annotations.
When should I use the mappedBy function?
When should I use the inversedBy function?
Is there a time when I should utilize neither?
Here’s an illustration:
/**
*
* @ORM\OneToOne(targetEntity="\custMod\Entity\Person", mappedBy="customer")
* @ORM\JoinColumn(name="personID", referencedColumnName="id")
*/
protected $person;
/**
*
* @ORM\OneToOne(targetEntity="\Auth\Entity\User")
* @ORM\JoinColumn(name="userID", referencedColumnName="id")
*/
protected $user;
/**
*
* @ORM\ManyToOne (targetEntity="\custMod\Entity\Company", inversedBy="customer")
* @ORM\JoinColumn (name="companyID", referencedColumnName="id")
*/
protected $company;
I conducted a quick Google search and came up with the following, but I’m still perplexed:
Asked by Developer
Solution #1
from doctrine documentation:
See https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html
Answered by Andreas Linden
Solution #2
The answers above were insufficient for me to comprehend what was going on, therefore after further investigation, I believe I have a method of describing it that will make sense to anyone who struggled to comprehend it as much as I did.
The INTERNAL DOCTRINE engine uses inversedBy and mappedBy to decrease the amount of SQL queries required to obtain the information you require. To be clear, your code will still operate if you don’t use inversedBy or mappedBy, but it will not be optimized.
Take a look at the following classes as an example:
class Task
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="task", type="string", length=255)
*/
private $task;
/**
* @var \DateTime
*
* @ORM\Column(name="dueDate", type="datetime")
*/
private $dueDate;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="tasks", cascade={"persist"})
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
}
class Category
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Task", mappedBy="category")
*/
protected $tasks;
}
These are the classes you’ll be taking. If you run the command to produce the schema (bin/console doctrine:schema:update —force —dump-sql, for example), you’ll note that the Category table lacks a column for tasks. (This is due to the fact that it lacks a column annotation)
The crucial thing to remember here is that the variable tasks exists just so that the internal doctrine engine may reference the reference above it, which states that it is mappedBy Category. Now, don’t be as perplexed as I was… The term ‘category’ does not correspond to the class name; rather, it refers to the ‘protected $category’ field on the Task class.
Similarly, the $category property on the Tasks class specifies that it is inversedBy=”tasks”; notice that this is plural; this is NOT THE PLURAL OF THE CLASS NAME, but simply because the property in the Category class is called “protected $tasks.”
It’s a lot easier to comprehend what inversedBy and mappedBy do and how to utilize them in this circumstance if you understand this.
Because it has to know what class (through the targetEntity command) and what variable (inversedBy=) on that class to ‘work backwards’ and acquire the category information from, the side that is accessing the foreign key, such as ‘tasks’ in my example, always gets the inversedBy attribute. The class that has the foreignkey id is the one that needs inversedBy, which is an easy method to remember.
Whereas with category and its $tasks property (which is not on the table, but is only part of the class for optimization purposes) being MappedBy ‘tasks,’ this officially establishes the relationship between the two entities, allowing doctrine to use JOIN SQL statements instead of two separate SELECT statements. Without mappedBy, the doctrine engine would have no idea what variable in the class ‘Task’ to put the category information from the JOIN statement.
I hope this clarifies things for you.
Answered by Joseph Astrahan
Solution #3
There is an owning side and an inverse side in a bidirectional connection.
put into mappedBy: A bidirectional relationship’s polar opposite. to refer to the side that owns it
The owning side of a bidirectional relationship is inversedBy: placed into To refer to its polar opposite
AND
mapped When a OneToOne, OneToMany, or ManyToMany mapping declaration is used, this attribute is used.
inversed When a OneToOne, ManyToOne, or ManyToMany mapping declaration is used, this attribute is used.
The side that contains the foreign key is the owning side of a bidirectional connection.
In Doctrine Documentation, there are two references to inversedBy and mappedBy: First Link, Second Link, Third Link, Fourth Link, Fifth Link, Sixth Link, Seventh Link,
Answered by ahmed hamdy
Solution #4
5.9.1 Having an Opposite Side
You can choose which entity is the owning and which is the flip side for Many-To-Many connections. From a developer’s perspective, there is a very easy semantic criteria to determine which side is better fit to be the owning side. Simply ask yourself which entity is in charge of connection management and choose that as the owning side.
Consider the two entities Article and Tag. When you want to link an Article to a Tag and vice versa, the Article is usually the one who makes the connection. You want to tie new articles to current or new tags whenever you create a new one. This is likely to be supported by your create Article form, which will allow you to specify the tags directly. This is why you should select Article as the owning side, as it simplifies the code:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html
Answered by Micheal Mouner Mikhail Youssif
Post is based on https://stackoverflow.com/questions/12493865/what-is-the-difference-between-inversedby-and-mappedby