16
votes

On this page of association mapping, there's an example in the manytomany section. But I don't understand which entity (group or user) is the owning side.

http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#many-to-many-bidirectional

I've put the code here too

<?php
/** @Entity */
class User
{
    // ...

    /**
     * @ManyToMany(targetEntity="Group", inversedBy="users")
     * @JoinTable(name="users_groups")
     */
    private $groups;

    public function __construct() {
        $this->groups = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

/** @Entity */
class Group
{
    // ...
    /**
     * @ManyToMany(targetEntity="User", mappedBy="groups")
     */
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...
}

Do I read this annotation like this: User is mappedBy groups so group is the entity that does the connection management, thus the owning side?

Also, I've read this in the docs:

For ManyToMany bidirectional relationships either side may be the owning side (the side  that defines the @JoinTable and/or does not make use of the mappedBy attribute, thus using   a default join table).

This lets me think that User would be the owning side as the JoinTable annotation is defined in that entity.

2
Possible duplicate of this stackoverflow.com/questions/12493865/…Developer

2 Answers

17
votes

But I don't understand which entity (group or user) is the owning side

The User entity is the owner. You have the relation of groups in User:

/**
 * @ManyToMany(targetEntity="Group", inversedBy="users")
 * @JoinTable(name="users_groups")
 */
private $groups;

Look above, $groups var contains the all groups associated to this user, but If you notice the property definition, $groups var has the same name of mappedBy value (mappedBy="groups"), as you did:

/**
 * @ManyToMany(targetEntity="User", mappedBy="groups")
 */
private $users;

What does mappedBy mean?

This option specifies the property name on the targetEntity that is the owning side of this relation.

16
votes

Taken from the docs:

In a one-to-one relation the entity holding the foreign key of the related entity on its own database table is always the owning side of the relation.

In a many-to-one relation the Many-side is the owning side by default, because it holds the foreign key. The OneToMany side of a relation is inverse by default, since the foreign key is saved on the Many side. A OneToMany relation can only be the owning side, if its implemented using a ManyToMany relation with join table and restricting the one side to allow only UNIQUE values per database constraint.

Now, I understand ManyToMany can be confusing some times.

For Many-To-Many associations you can choose which entity is the owning and which the inverse side. There is a very simple semantic rule to decide which side is more suitable to be the owning side from a developers perspective. You only have to ask yourself, which entity is responsible for the connection management and pick that as the owning side.

Take an example of two entities Article and Tag. Whenever you want to connect an Article to a Tag and vice-versa, it is mostly the Article that is responsible for this relation. Whenever you add a new article, you want to connect it with existing or new tags. Your createArticle form will probably support this notion and allow to specify the tags directly. This is why you should pick the Article as owning side, as it makes the code more understandable:

<?php
class Article
{
    private $tags;

    public function addTag(Tag $tag)
    {
        $tag->addArticle($this); // synchronously updating inverse side
        $this->tags[] = $tag;
    }
}

class Tag
{
    private $articles;

    public function addArticle(Article $article)
    {
        $this->articles[] = $article;
    }
}

This allows to group the tag adding on the Article side of the association:

<?php
$article = new Article();
$article->addTag($tagA);
$article->addTag($tagB);

So, in short, whatever makes more sense to you. You choose the owning and the inverse side of the relationship. :)

Source: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html