5
votes

I realize a web application with Symfony 2 from an existing database.

I have set up an entity with a primary key consisting of two foreign keys.

example:

Entity1 with a composite primary key: property1 (PK), property2 (PK) Entity2 primary key consists of two foreign keys: property1 (PK FK), property2 (PK FK), propriete3 (PK)

I don't how to implement this association:

In the entity2 i do :

/** 
 * @ORM\ManyToOne (targetEntity = "Entity1") 
 * @ORM\JoinColumns ({
 *    @ORM\JoinColumn (name = "property1" referencedColumnName = "property1") 
 *    @ORM\JoinColumn (name = "property2" referencedColumnName = "property2") 
 *    @ORM\Id 
 * @}) 
 */ 
private $entity1; 

But I get an error:

It is not possible to map entity 'ExempleBundle\Entity\Entite1' with a composite primary key as part of the primary key of another entity 'ExempleBundle\Entity\Entite2#entite1'.

How to properly handle this kind of association with Doctrine

I tried to follow this example but I do not understand : http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html#use-case-1-dynamic-attributes

Can you give an example of two entities with a similar case and especially on how to make a joint in this case.

3

3 Answers

4
votes

I found a work-around that gets around the issue, by defining a separate foreign key, using the original foreign key columns as the join columns.

/** @Id @Column(...) */
protected $property1;
/** @Id @Column(...) */
protected $property2;
/** @Id @Column(...) */
protected $property3;

/**
 * @ManyToOne(targetEntity="Entity1")
 * @JoinColumns({
 *     @JoinColumn(name="property1", referencedColumnName="property1"),
 *     @JoinColumn(name="property2", referencedColumnName="property2")
 * })
 **/
protected $foreignObject;
1
votes

It is a example that works:

<?php

namespace Project\WorkflowBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="opinion")
 */
class Opinion
{
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="\Project\WorkflowBundle\Entity\Comision_Proyecto", inversedBy="opiniones")
     */
    protected $comision;
    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="\Project\WorkflowBundle\Entity\Persona", inversedBy="opiniones")
     */
    protected $persona;
    /**
     * @ORM\OneToMany(targetEntity="\Project\WorkflowBundle\Entity\Comentario", mappedBy="opinion")
     */
    protected $comentarios;
}

the other class:

<?php


namespace Project\WorkflowBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="comentario")
 */
class Comentario
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;
    /**
     * @ORM\Column(type="boolean")
     */
    protected $privado;
    /**
     * @ORM\ManyToOne(targetEntity="\Project\WorkflowBundle\Entity\Opinion")
     *  @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="comision_id", referencedColumnName="comision_id"),
     *   @ORM\JoinColumn(name="persona_id", referencedColumnName="persona_id")
     * })
     */
    protected $opinion;
}
-1
votes

Doctrine2 do not manage foreign composite keys to reference an entity with its composite primary keys

The cases where Doctrine2 manage correctly composite primary keys are mainly :

  • OneToMany: The associated entity (ArticleAttributes) uses as primary key, the primary key of the referenced entity (Artile) and an other self field (attribute)

Article (id, title, ...), ArticleAttributes (#article_id, #attribute, value, ...)

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html#use-case-1-dynamic-attributes

In your case, you want to reference an entity which hasn't got a unqiue identifier but a composite keys, Doctrine do not manage this case. You can only have composite key for association entity type.

Generally, I avoid to use composite keys for the main models. I reserved composite keys for model of association type.

So a solution is to use a primary key for your main model Entity1

Hope this helps.