Major Productions
Major Productions

Reputation: 6042

Doctrine 2 - One-to-Many unidirectional

A couple questions regarding creating a One-to-Many unidirectional relationship in Doctrine 2:

  1. Is a join table necessary?
  2. The docs say "look at this example," but all I see is the generated schema. Anyone mind whipping up a quick example so I can get the annotations correct?

Upvotes: 5

Views: 20253

Answers (5)

Davide Bicego
Davide Bicego

Reputation: 632

I'm a bit late to the party but this is how I do it:

<entity name="User" table="users">
    <id name="id" type="integer" column="id">
      <generator strategy="IDENTITY"/>
    </id>

    <one-to-many field="children" target-entity="User" mapped-by="father">
    </one-to-many> 

    <many-to-one field="father" target-entity="User" inversed-by="children">
        <!-- without this row it doesn't work -->
        <join-column name="id" referenced-column-name="id" />
    </many-to-one>
</entity>

Upvotes: 0

Imeksbank
Imeksbank

Reputation: 114

This works well with Doctrine 2 + Zend Framework 2.5 while fetching one-to-many http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

In my case i had to retrieve Products with their Documents (each Product minimum 5 Documents)

The ArrayCollection does it pretty well itself.

In viewer you have only to foreach the object Product and then once again foreach $product->getDoc() thats it.

Upvotes: 0

Alex
Alex

Reputation: 1573

This demonstrates a one-to-many relationship, whereby a User can have many Reports, and one Report can only belong to one User.

class User
{
    // ...

    /**
     * @OneToMany(targetEntity="Report", mappedBy="user")
     */
    protected $reports;

    public function __construct()
    {
        $this->reports = new ArrayCollection();
    }

    public function addReport(\Namespace\To\Report $report)
    {
        $this->report[] = $report;
    }

    public function getReports()
    {
        return $this->reports;
    }
}

and

class Report
{
    // ...

    /**
     * @ManyToOne(targetEntity="User", inversedBy="reports")
     * @JoinColumn(name="user_id", referencedColumnName="id")
     */
    protected $user;

    public function setUser(\Namespace\To\User $user)
    {
        $this->user = $user;
    }

    public function getUser()
    {
        return $this->user;
    }
}

In this instance, to create a Report and associate it with a User, we would:

// create a User (or find an existing one)
$user = new User();
// create the Report
$report = new Report();
// add the User to the Report
$report->setUser($user);
// then persist it, etc ...

Upvotes: 2

AlixB
AlixB

Reputation: 1228

You were on the 2.0.x version of the documentation. Check this one. You will have the example.

So yes, you can avoid the annotation in one of the two classes.

Upvotes: 2

Thomas K
Thomas K

Reputation: 6196

Nope it is not. Try this:

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

    /**
     * @ORM\OneToMany(targetEntity="My\AwesomeBundle\Entity\Bar", mappedBy="foo")
     */
    protected $bars;
}

class Bar
{
    /**
     * @ORM\ManyToOne(targetEntity="My\AwesomeBundle\Entity\Foo", inversedBy="bars")
     */
    protected $foo;
}

Upvotes: 0

Related Questions