简体   繁体   中英

Doctrine - Composite IDs

I am using symfony2 with the Doctrine entities and I have a problem with the next:

我的数据库

I know I could solve the problem putting an ID to the "club_has_torneo" and turning it into an entity, but to me creating an entity for that looks like something that should not be done. So I wanted to know if there is a way to solve this issue or if I have to do what I think I have to.

Thank you in advance.

I guess I'll submit my own two cents worth.

ORM stands for Object Relational Mapper. The basic idea is to figure out how to map your objects without worrying too much about the database schema. So you have three domain model entities: torneo, club and nadador. Great. Figure out how your application will use these entities. Don't worry about how the relations will end up being stored.

Once you have a working domain model then worry about persistence. The three domain entities clearly map to three doctrine entities. As far as the relations go, I personally am not a big fan of composite primary keys. I think they just complicate things while adding little value. So I would make Doctrine entities for your two has tables and just given them their own primary database id.

Note that these are Doctrine entities not domain entities. Your application code should never need to deal with these relational doctrine entities at all. So in my opinion

creating an entity for that looks like something that should not be done

does not apply here. It is just a persistence detail.

I think the best solution is indeed to make a entity for your club_has_torneo table. This ClubHasTorneo entity has club_id and torneo_id as composite keys and holds the owning side of a many-to-many relationship between your ClubHasTorneo entity and Nadador entity. This relationship can be done with a join table using the 3 keys. Check the code below on how to do that.

Your database scheme will look exactly like you drew it.
Your ClubHasTorneo entity would look something like this:

<?php

namespace Application\Entity;

use Application\Entity\Club;
use Application\Entity\Torneo;
use Application\Entity\Nadador;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="club_has_torneo")
 */
class ClubHasTorneo
{
    /** MANY-TO-ONE BIDIRECTIONAL, OWNING SIDE
     * @var Club
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Application\Entity\Club", inversedBy="clubHasTorneos", cascade={"persist"})
     * @ORM\JoinColumn(name="club_id", referencedColumnName="id")
     */
    protected $club;

    /** MANY-TO-ONE BIDIRECTIONAL, OWNING SIDE
     * @var Torneo
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Application\Entity\Torneo", inversedBy="clubHasTorneos")
     * @ORM\JoinColumn(name="torneo_id", referencedColumnName="id")
     */
    protected $torneo;

    /** MANY-TO-MANY BIDIRECTIONAL, OWNING SIDE
     * @var Collection
     * @ORM\ManyToMany(targetEntity="Application\Entity\Nadador", inversedBy="clubHasTorneos")
     * @ORM\JoinTable(name="club_has_torneo_has_nadador",
     *     joinColumns={
     *         @ORM\JoinColumn(name="club_id", referencedColumnName="club_id"),
     *         @ORM\JoinColumn(name="torneo_id", referencedColumnName="torneo_id")
     *     },
     *     inverseJoinColumns={
     *         @ORM\JoinColumn(name="nadador_id", referencedColumnName="id")
     *     }
     * )
     */
    protected $natadors;

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

    // setters and getters
}

my 5 cents

If you want your implementation to match the drawn table structure, then (in my opinion) you need create an entity out of the 'club_has_torneo' table (for 'club_has_torneo_has_matador' you don't need to).

The rationale being that if you try to achieve this without creating the entity, you would need to create the entity associations so, that the 'natador' table references the 'club' and 'torneo' directly - in which case the actual database relations wouldn't match with your drawn table relationship anymore (ie the natador wouldn't have relationship to the 'club_has_torneo' table).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM