Doctrine2复合主键中具有复合外键的实体 [英] Doctrine2 Map entities with composite foreign keys in the composite primary keys

查看:143
本文介绍了Doctrine2复合主键中具有复合外键的实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型有很多表,但在这种情况下,我们只需要三个。



关键是一个复合主键也是一个key(复合)和Symfony抛出这个异常:



MappingException:不可能映射实体'Your\SomethingBundle\Entity\\ \\ Empleado'与复合主键一起作为另一个实体的主键的一部分'Your\SomethingBundle\Entity\EmpleadoHorario#empleado'

>

这里我解释一下关系:



1º沙龙,它有一个主键 ID / p>

2ºEmpleado,它具有复合主键 ID,Salon_id ,并且还在主键中,引用沙龙的前导键: Salon_id



3ºEmpleadoHorario:它具有复合主键 Fecha,Empleado_id,Salon_id ,还有主键,一个前键引用沙龙: Salon_id 和Empleado: Empleado_id,Salon_id



所有的关系也都是反联合。以下是代码:



沙龙实体:

 code> / ** 
*沙龙
*
* @ ORM\Table(name =salon)
* @ ORM\Entity
* /
class Salon
{
/ **
* @var string
*
* @ ORM\Column(name =id type =string,length = 50,nullable = false)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =IDENTITY)
* /
private $ id;

//更多字段...

/ **
* @var array_collection
*
* @ ORM\OneToMany targetEntity =Empleado,mappedBy =salon)
* /
private $ empleados;

/ **
* @var array_collection
*
* @ ORM\OneToMany(targetEntity =EmpleadoHorario,mappedBy =salon)
* /
private $ empleadoHorarios;

// Getters& Setters ...
}

Empleado 实体: / p>

  / ** 
* Empleado
*
* @ ORM\Table(name = empleado)
* @ ORM\Entity
* /
class Empleado
{
/ **
* @var整数
*
* @ ORM\Column(name =id,type =bigint,nullable = false)
* @ ORM\Id
* @ ORM\GeneratedValue =NONE)
* /
private $ id;

/ **
* @var string
*
* @ ORM\JoinColumn(name =salon_id,referencedColumnName =id,nullable = false )
* @ ORM\ManyToOne(targetEntity =Salon,inversedBy =empleados)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =NONE )
* /
private $ salon;

//更多字段...

/ **
* @var array_collection
*
* @ ORM\OneToMany targetEntity =EmpleadoHorario,mappedBy =salon)
* /
private $ empleadoHorarios;

// Getters& setter ...

}

最后, EmpleadoHorario 实体:

  / ** 
* EmpleadoHorario
*
* @ORM \Table(name =empleado_horario)
* @ ORM\Entity
* /
class EmpleadoHorario
{
/ **
* @ var \DateTime
*
* @ ORM\Column(name =fecha,type =date,nullable = false)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =NONE)
* /
private $ fecha;

/ **
* @var string
*
* @ ORM\JoinColumn(name =salon_id,referencedColumnName =id,nullable = false )
* @ ORM\ManyToOne(targetEntity =Salon,inversedBy =empleadoHorarios)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =NONE )
* /
private $ salon;

/ **
* @var整数
*
* @ ORM\ManyToOne(targetEntity =Empleado,inversedBy =empleadoHorarios)
* @ ORM\JoinColumns({
* @ ORM\JoinColumn(name =salon_id,referencedColumnName =salon_id,nullable = false),
* @ ORM\JoinColumn(name = empleado_id,referencedColumnName =id,nullable = false)
*})
* @ ORM\Id
* @ ORM\GeneratedValue(strategy =NONE)
* /
private $ empleado;

//更多字段...

// Getters& Setters ...

}

如上所述,问题似乎在 EmpleadoHorario.empleado 字段中,这是一个复合主键的一部分,也是复合的主键。



StackOverflow的其他答案。 com建议Mapping继承,但我甚至不知道它是如何工作的。我在阅读这篇文章后尝试了两次,但是我无法解决我的问题。

解决方案

此示例代码是我的(临时)解决方案的说明:

 <?php 
命名空间X;

使用Doctrine\ORM\Mapping作为Orm;

/ **
* @ Orm\Entity
* @ Orm\Table(name =A)
* /
class A {
/ **
* @ Orm\Id
* @ Orm\Column(name =id,type =integer)
* @ Orm\ GeneratedValue(strategy =NONE)
*
* @var integer
* /
private $ id;

/ **
* @ Orm\Id
*
* @var string
* /
private $ otherId;

/ **
* @ Orm\OneToMany(targetEntity =B,fetch =LAZY,mappedBy =a)
*
* @var数组
* /
private $ collectionOfB;

// getter,setter和其他道具/方法
}
/ **
* @ Orm\Entity
* @ Orm\Table (name =B)
* /
class B {
/ **
* @ Orm\Id
* @ Orm\Column(name = code)
*
* @var string
* /
private $ code;

/ **
* @ Orm\Id
* @ Orm\Column(name =a_id,type =integer)
*
* @var整数
* /
private $ a_id;

/ **
* @ Orm\Id
* @ Orm\Column(name =a_other_id)
*
* @var整数
* /
private $ a_other_id;

/ **
* @ Orm\ManyToOne(targetEntity =A,fetch =LAZY,inversedBy =collectionOfB)
* @ Orm\JoinColumns ({@ Orm\JoinColumn(name =a_id,referencedColumnName =id),@ Orm\JoinColumn(name =a_other_id,referencedColumnName =other_id)})
*
* @var A
* /
private $ a;

/ **
* @ Orm\OneToOne(targetEntity =C,fetch =LAZY,mappedBy =b)
*
* @var C
* /
private $ c;

// bla bla bla
}
/ **
* @ Orm\Entity
* @ Orm\Table(name =C )
* /
class C {
/ **
* @ Orm\Id
* @ Orm\Column(name =a_id,type =integer)
*
* @var整数
* /
private $ a_id;

/ **
* @ Orm\Id
* @ Orm\Column(name =a_other_id)
*
* @var整数
* /
private $ a_other_id;

/ **
* @ Orm\Id
* @ Orm\Column(name =b_code)
*
* @var string
* /
private $ b_code;

/ **
*
* @ Orm\OneToOne(targetEntity =B,fetch =LAZY,inversedBy =c)
* @ Orm\JoinColumns({@ Orm\JoinColumn(name =a_id,referencedColumnName =a_id),@ Orm\JoinColumn(name =a_other_id,referencedColumnName =a_other_id),@ Orm\JoinColumn (name =b_code,referencedColumnName =b_code)})
*
* @var B
* /
private $ b;

// bla bla bla
}


I have a model which has many tables, but in this case we only need three.

The point is that the composite primary key of one is also the foreing key (composite too) and Symfony throws this exception:

MappingException: It is not possible to map entity 'Your\SomethingBundle\Entity\Empleado' with a composite primary key as part of the primary key of another entity 'Your\SomethingBundle\Entity\EmpleadoHorario#empleado'.

Here I explain the relationship:

1º Salon, it has a primary key ID

2º Empleado, it has a composite primary key ID, Salon_id and, also in the primary key, a foreing key referencing Salon: Salon_id

3º EmpleadoHorario: it has a composite primary key Fecha, Empleado_id, Salon_id and, also in the primary key, two a foreing keys referencing Salon: Salon_id, and Empleado: Empleado_id, Salon_id

All the relations has also the inverse union. Here is the code:

The Salon Entity:

/**
 * Salon
 *
 * @ORM\Table(name="salon")
 * @ORM\Entity
 */
class Salon
{
    /**
     * @var string
     *
     * @ORM\Column(name="id", type="string", length=50, nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    // More fields...

    /**
     * @var array_collection 
     * 
     * @ORM\OneToMany(targetEntity="Empleado", mappedBy="salon")
     */
    private $empleados;

    /**
     * @var array_collection 
     * 
     * @ORM\OneToMany(targetEntity="EmpleadoHorario", mappedBy="salon")
     */
    private $empleadoHorarios;

    // Getters & Setters...
}

The Empleado Entity:

/**
 * Empleado
 *
 * @ORM\Table(name="empleado")
 * @ORM\Entity
 */
class Empleado
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="bigint", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\JoinColumn(name="salon_id", referencedColumnName="id", nullable=false)
     * @ORM\ManyToOne(targetEntity="Salon", inversedBy="empleados")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $salon;

    // More fields...

    /**
     * @var array_collection 
     * 
     * @ORM\OneToMany(targetEntity="EmpleadoHorario", mappedBy="salon")
     */
    private $empleadoHorarios;

    // Getters & setters...

}

And finally the EmpleadoHorario Entity:

/**
 * EmpleadoHorario
 *
 * @ORM\Table(name="empleado_horario")
 * @ORM\Entity
 */
class EmpleadoHorario
{
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="fecha", type="date", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $fecha;

    /**
     * @var string
     *
     * @ORM\JoinColumn(name="salon_id", referencedColumnName="id", nullable=false)
     * @ORM\ManyToOne(targetEntity="Salon", inversedBy="empleadoHorarios")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $salon;

    /**
     * @var integer
     *
     * @ORM\ManyToOne(targetEntity="Empleado", inversedBy="empleadoHorarios")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="salon_id", referencedColumnName="salon_id", nullable=false),
     *   @ORM\JoinColumn(name="empleado_id", referencedColumnName="id", nullable=false)
     * })
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $empleado;

    // More fields...

    // Getters & Setters...

}

As I said above, the problem seems to be in the EmpleadoHorario.empleado field, which is part of a composite primary key and also composite foreing key.

Other answers across StackOverflow.com suggest the Mapping Inheritance, but I don't even know how it works. I tried twice after reading this but I couldn't solve my problem.

解决方案

This sample code is illustration of my (temporary) solution :

    <?php
namespace X;

use Doctrine\ORM\Mapping as Orm;

/**
 * @Orm\Entity
 * @Orm\Table(name="A")
 */
class A {
    /**
     * @Orm\Id
     * @Orm\Column(name="id", type="integer")
     * @Orm\GeneratedValue(strategy="NONE")
     * 
     * @var integer
     */
    private $id;

    /**
     * @Orm\Id
     * 
     * @var string
     */
    private $otherId;

    /**
     * @Orm\OneToMany(targetEntity="B", fetch="LAZY", mappedBy="a")
     * 
     * @var array
     */
    private $collectionOfB;

    // getter, setter and other props/methods
}
/**
 * @Orm\Entity
 * @Orm\Table(name="B")
 */
class B {
    /**
     * @Orm\Id
     * @Orm\Column(name="code")
     * 
     * @var string
     */
    private $code;

    /**
     * @Orm\Id
     * @Orm\Column(name="a_id", type="integer")
     * 
     * @var integer
     */
    private $a_id;

    /**
     * @Orm\Id
     * @Orm\Column(name="a_other_id")
     *
     * @var integer
     */
    private $a_other_id;

    /**
     * @Orm\ManyToOne(targetEntity="A", fetch="LAZY", inversedBy="collectionOfB")
     * @Orm\JoinColumns({@Orm\JoinColumn(name="a_id", referencedColumnName="id"), @Orm\JoinColumn(name="a_other_id", referencedColumnName="other_id")})
     * 
     * @var A
     */
    private $a;

    /**
     * @Orm\OneToOne(targetEntity="C", fetch="LAZY", mappedBy="b")
     * 
     * @var C
     */
    private $c;

    // bla bla bla
}
/**
 * @Orm\Entity
 * @Orm\Table(name="C")
 */
class C {
    /**
     * @Orm\Id
     * @Orm\Column(name="a_id", type="integer")
     * 
     * @var integer
     */
    private $a_id;

    /**
     * @Orm\Id
     * @Orm\Column(name="a_other_id")
     *
     * @var integer
     */
    private $a_other_id;

    /**
     * @Orm\Id
     * @Orm\Column(name="b_code")
     *
     * @var string
     */
    private $b_code;

    /**
     * 
     * @Orm\OneToOne(targetEntity="B", fetch="LAZY", inversedBy="c")
     * @Orm\JoinColumns({@Orm\JoinColumn(name="a_id", referencedColumnName="a_id"), @Orm\JoinColumn(name="a_other_id", referencedColumnName="a_other_id"), @Orm\JoinColumn(name="b_code", referencedColumnName="b_code")})
     * 
     * @var B
     */
    private $b;

    // bla bla bla
}

这篇关于Doctrine2复合主键中具有复合外键的实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆