我对Doctrine2很陌生,并试图为以下DB结构创建实体:

我希望在机器类的一个属性中将所有机器部件作为数组。我试过这个:
class Machine {
....
/**
* @var array
* @ORM\OneToMany(targetEntity="MachineHasPart", mappedBy="machine", cascade={"persist", "remove"}, orphanRemoval=TRUE)
*/
private $parts;
....
public function getParts () {
return array_map(
function ($machineHasPart) {
return $machineHasPart->getPart();
},
$this->parts->toArray()
);
}
}其中MachineHasPart是中间实体/表(如machineHasCylinder等)的@MappedSuperclass,但是它失败了:
执行'SELECT从machineHasPart t0‘时发生异常。
我应该重组我的数据库以便在这里使用ORM吗?还是有办法解决我的案子?
发布于 2015-08-03 08:12:14
您不能查询@MappedSuperClass。在6.1。映射超类中也提到了这一点
映射的超类不能是实体,它不是可查询的和持久的。
这意味着您必须将目标实体更改为可查询的对象,或者必须将MachineHasPart更改为实体并更改为单表继承。
当我查看您的数据库结构时,我建议将您的Machine实体更改为三个独立的部件关系。一个用于皮带,一个用于气缸,另一个用于齿轮。
然后,您将有三个方法( getBelts、getCylinders和getGears ),而不是泛型的getCylinders。
如果这真的不是你想要的,那么你可以留下评论。
更新
您也可以通过类继承来解决这个问题。首先,创建一个同时也是一个实体的基类Part,并在其他类Belt、Cylinder和Gear中使用它。
部件:
<?php
namespace Machine\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Part
*
* @ORM\Entity
* @ORM\Table("part")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discriminator", type="string")
* @ORM\DiscriminatorMap({
* "part" = "Part",
* "gear" = "Gear",
* "cylinder" = "Cylinder",
* "belt" = "Belt",
* })
* @property int $id
*/
class Part
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var Machine
* @ORM\ManyToOne(targetEntity="Machine\Entity\Machine", inversedBy="parts")
* @ORM\JoinColumn(name="machine_id", referencedColumnName="id", nullable=true)
*/
protected $machine;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* @param int $id
* @return self
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
//... add setters and getters for machine as normal ...
}在其他部分中扩展这个类:
带:
<?php
namespace Machine\Entity;
/**
* Belt
*
* @ORM\Entity
*/
class Belt extends Part
{
}气缸:
<?php
namespace Machine\Entity;
/**
* Cylinder
*
* @ORM\Entity
*/
class Cylinder extends Part
{
}齿轮:
<?php
namespace Machine\Entity;
/**
* Gear
*
* @ORM\Entity
*/
class Gear extends Part
{
}现在,在您的机器中,相关部件如下所示。
机器:
<?php
namespace Machine\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Machine
*
* @ORM\Entity
* @ORM\Table("machine")
* @property int $id
*/
class Machine
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* @param int $id
* @return self
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @var Collection
* @ORM\OneToMany(targetEntity="Machine\Entity\Part", mappedBy="machine")
*/
protected $parts;
public function __constuct()
{
$parts = new ArrayCollection();
}
/**
*
* @return Collection
*/
public function getParts()
{
return $this->parts;
}
//... add setters and getters for parts as normal ...
}在其他部分中扩展这个类:
发布于 2015-08-03 18:06:46
在第6.1章中的Doctrine2文档。映射超类中进一步阅读(由@Wilt引用):
..。此外,只有当映射的超类目前只在一个实体中使用时,才有可能出现多到多的关联.
这意味着在这种情况下ORM映射没有帮助。我不能同时通过一个MachineHasCylinder、MachineHasBelt和MachineHasGear三个实体通过MappedSupperclass收集数据。我认为使用DQL或原生SQL是解决这个问题的唯一方法。
https://stackoverflow.com/questions/31777859
复制相似问题