Я думаю, что вы не поняли, раздел руководства, который вы цитировали, озаглавлен «Влияние на производительность», вам не говорят, что не может сделать это, только что есть производительность последствия, если вы делаете. Это имеет смысл для отложенной загрузки - для разнородных коллекций объектов STI вам нужно перейти в базу данных и загрузить объект, прежде чем вы узнаете, какой это будет класс, поэтому отложенная загрузка невозможна / не имеет смысла. Я сам сейчас изучаю Doctrine 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, вы заметите, что когда targetEntity 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')
НТН.