8

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.

D. Schreier
  • 1,700
  • 1
  • 22
  • 34
SayDevNet
  • 131
  • 1
  • 2
  • 4

3 Answers3

5

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;
Chase
  • 9,289
  • 5
  • 51
  • 77
Enid van Gils
  • 51
  • 1
  • 3
  • Thanks, but if I set (for example) $property1, $property2 and $property3, these fields become null. It works fine after deleting $foreignObject. Is there a way to use both? – schellingerht Dec 05 '16 at 16:06
2

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;
}
Jose Luis
  • 37
  • 3
  • Your solution won't work, as in migrations you will get FOREIGN KEY (opinion_id) REFERENCES opinion (comision_id, persona_id) – Serhii Smirnov Oct 31 '22 at 12:05
-1

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.

BADAOUI Mohamed
  • 2,146
  • 1
  • 17
  • 14
  • It seems you're wrong Doctrine manages associations by composite keys. That is not trouble. Trouble is that keys used for association seem like can not be a part of PK simultaneously which is written in error: `It is not possible to map entity '...' with a composite primary key as part of the primary key of another entity '...'`. There is ugly solution for this case: http://stackoverflow.com/questions/19008582/doctrine2-map-entities-with-composite-foreign-keys-in-the-composite-primary-keys – zelibobla Apr 10 '15 at 13:09
  • Please read correctly my answer, I never said that "Doctrine [do not] manages associations by composite keys" On the contrary I said that Doctrine2 manage correctly composite primary keys in certains cases. – BADAOUI Mohamed Apr 17 '15 at 14:03
  • IMHO, I do not think that what you exactly expect is possible. Only cases that I have mentioned are well managed by doctrine 2 – BADAOUI Mohamed Apr 28 '15 at 12:05