具有关联和继承的学说

时间:2013-08-13 01:06:34

标签: php symfony doctrine-orm multiple-inheritance single-table-inheritance

我遇到了Doctrine,继承和映射问题。这是一个基于城市管理的网页游戏。我不会复制所有代码,不是因为它是秘密,而是因为我已经有太多不适合这里了。

总体设计如下:

每个城镇都有多个相对相似的结构,然后我决定做一个如下的MappedSuperClass

/**
* @ORM\MappedSuperclass
*/

class StructuresSuperClass{

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
private $id;

/**
* @ORM\ManyToOne(targetEntity="BuildingType")
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $type;

/**
* @ORM\ManyToOne(targetEntity="Town", cascade={"persist"})
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $town;

在结构中有路线,建筑物和建筑物中有一个特殊的城镇中心,它有自己的实体,如下:

路线:

use Spagi\GameBundle\Entity\StructuresSuperClass as SSC;

/**
 * @ORM\Entity
 * @ORM\Table(name="Route")
 */
class Route extends SSC{

/**
* @ORM\OneToMany(targetEntity="RouteOrders", mappedBy="route",  cascade={"all"}, orphanRemoval=true)
*/
protected $orders;

/**
* @ORM\ManyToOne(targetEntity="Building", cascade={"persist", "remove"})
* @ORM\JoinColumn(onDelete="CASCADE")
*/
protected $origin;

/**
* @ORM\ManyToOne(targetEntity="Building", cascade={"persist", "remove"})
* @ORM\JoinColumn(onDelete="CASCADE")
*/
protected $destination;

建筑物:

use Spagi\GameBundle\Entity\StructuresSuperClass as SSC;

/**
* @ORM\Entity
* @ORM\Table(name="Building")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"TC" = "TownCenter", "Building" = "Building"})
*/

class Building extends SSC{

/**
 * @ORM\OneToOne(targetEntity="Inventory", cascade={"persist", "remove"})
 * @ORM\JoinColumn(onDelete="CASCADE")
 */
private $inventory;

/**
 * @ORM\Column(type="integer")
 */
private $radius;

/**
 * @ORM\Column(type="integer")
 */
private $theta;

和TownCenter:

use Spagi\GameBundle\Entity\Building as Buildings;

/**
* @ORM\Entity
*/

class TownCenter extends Buildings{
public function __construct(){
    $this->setRadius(0);
    $this->setTheta(0);
    parent::__construct();
}

在城镇实体中,我需要分别访问这些,所以我创建了3个OneToMany

/**
* @ORM\Entity
* @ORM\Table(name="Town")
*/

class Town{

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;

/** SNIP **/

/**
 * @ORM\OneToMany(targetEntity="Building", mappedBy="town",  cascade={"all"}, orphanRemoval=true)
 */
protected $buildings;

/**
 * @ORM\OneToMany(targetEntity="TownCenter", mappedBy="town",  cascade={"all"}, orphanRemoval=true)
 */
protected $townCenter;

/**
 * @ORM\OneToMany(targetEntity="Route", mappedBy="town",  cascade={"all"}, orphanRemoval=true)
 */
protected $routes;

问题是我总是收到一条学说警告我的实体无效,如下所示

The field Spagi\GameBundle\Entity\Town#buildings is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Spagi\GameBundle\Entity\Building#town does not contain the required 'inversedBy=buildings' attribute.
The field Spagi\GameBundle\Entity\Town#townCenter is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Spagi\GameBundle\Entity\TownCenter#town does not contain the required 'inversedBy=townCenter' attribute.
The field Spagi\GameBundle\Entity\Town#routes is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity Spagi\GameBundle\Entity\Route#town does not contain the required 'inversedBy=routes' attribute.

根据我的理解,随着时间的推移和数据库的增长,这将导致性能下降。这个关系Building#town,TownCenter#town和Route#town都是从同一个文件继承的。我不能写一个inversedBy = {'buildings','townCenter','routes'}(我还没有尝试,但我对此表示怀疑)。

但是我想知道除了在每个实体中定义$ town之外是否有解决这个问题的方法,从而错过了继承点。

1 个答案:

答案 0 :(得分:1)

您无法在超类中进行映射。你必须在每个子类中映射Town。

因此,您的路线将使用inversedBy =“route”映射城镇, 并且您的建筑物将使用inversedBy =“building”映射城镇 等