我认为你误解了,你引用的手册中标题为“性能影响”的部分,他们并没有告诉你你不能这样做,只是说如果你这样做,就会对性能产生影响。这对于延迟加载是有意义的 - 对于STI实体的异构集合,您必须转到数据库并加载实体,然后才能知道它将是什么类,因此延迟加载是不可能的/没有意义。我现在正在自己学习教义2,所以我模拟了你的例子,以下工作正常:
namespace Entities;
/**
* @Entity
* @Table(name="pets")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="pet_type", type="string")
* @DiscriminatorMap({"cat" = "Cat", "dog" = "Dog"})
*/
class Pet
{
/** @Id @Column(type="integer") @generatedValue */
private $id;
/** @Column(type="string", length=300) */
private $name;
/** @ManyToOne(targetEntity="User", inversedBy="id") */
private $owner;
}
/** @Entity */
class Dog extends Pet
{
/** @Column(type="string", length=50) */
private $kennels;
}
/** @Entity */
class Cat extends Pet
{
/** @Column(type="string", length=50) */
private $cattery;
}
/**
* @Entity
* @Table(name="users")
*/
class User
{
/** @Id @Column(type="integer") @generatedValue */
private $id;
/** @Column(length=255, nullable=false) */
private $name;
/** @OneToMany(targetEntity="Pet", mappedBy="owner") */
private $pets;
}
...和测试脚本....
if (false) {
$u = new Entities\User;
$u->setName("Robin");
$p = new Entities\Cat($u, 'Socks');
$p2 = new Entities\Dog($u, 'Rover');
$em->persist($u);
$em->persist($p);
$em->persist($p2);
$em->flush();
} else if (true) {
$u = $em->find('Entities\User', 1);
foreach ($u->getPets() as $p) {
printf("User %s has a pet type %s called %s\n", $u->getName(), get_class($p), $p->getName());
}
} else {
echo " [1]\n";
$p = $em->find('Entities\Cat', 2);
echo " [2]\n";
printf("Pet %s has an owner called %s\n", $p->getName(), $p->getOwner()->getName());
}
我所有的猫和狗都加载为正确的类型:
如果你看一下生成的SQL,你会发现当OneToMany目标实体是“pet”时,你得到的SQL是这样的:
SELECT t0.id AS id1, t0.name AS name2, t0.owner_id AS owner_id3, pet_type,
t0.cattery AS cattery4, t0.kennels AS kennels5 FROM pets t0
WHERE t0.owner_id = ? AND t0.pet_type IN ('cat', 'dog')
但是当它设置为 Cat 时,您会得到以下结果:
SELECT t0.id AS id1, t0.name AS name2, t0.cattery AS cattery3, t0.owner_id
AS owner_id4, pet_type FROM pets t0 WHERE t0.owner_id = ? AND t0.pet_type IN ('cat')
呵呵。