Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine Composite primary key foreign key

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.

like image 335
SayDevNet Avatar asked Nov 03 '14 15:11

SayDevNet


People also ask

What is primary key foreign key and composite key?

A key which has multiple attributes to uniquely identify rows in a table is called a composite key. An artificial key which aims to uniquely identify each record is called a surrogate key. Primary Key never accept null values while a foreign key may accept multiple null values.

Can a composite primary key be a foreign key?

This is not possible. The foreign key can not refer to part of composite primary key of other table. Because it is supposed to be one-to-one relationship and if you refer just part of primary-key, there might be more than one parent record available, which is neither allowed nor possible.

What is composite primary key in JPA?

A composite primary key, also called a composite key, is a combination of two or more columns to form a primary key for a table. In JPA, we have two options to define the composite keys: the @IdClass and @EmbeddedId annotations.

Is composite and foreign key same?

A composite key specifies multiple columns for a primary-key or foreign-key constraint. The next example creates two tables. The first table has a composite key that acts as a primary key, and the second table has a composite key that acts as a foreign key.


2 Answers

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;
like image 83
Enid van Gils Avatar answered Dec 08 '22 01:12

Enid van Gils


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;
}
like image 38
Jose Luis Avatar answered Dec 08 '22 02:12

Jose Luis