У меня есть файл /src/AppBundle/Entity/Questionnaire.php с 3 классами сущностей, где я пытаюсь реализовать наследование одной таблицы с Doctrine 2 на Symfony 2.7. Опросный лист является родительским абстрактным классом, и есть 2 дочерних класса FirstQuestions а также SecondsQuestions это расширяет Опросный лист. Я выбрал эту модель, потому что мне нужно записать данные в таблицу в 2 этапа. Код этого файла ниже:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Questionnaire
*
* @ORM\Entity
* @ORM\Table(name="questionnaire")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"firstquestions" = "FirstQuestions", "secondquestions" = "SecondQuestions"})
*/
abstract class Questionnaire {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}
/**
* FirstQuestions
*/
class FirstQuestions extends Questionnaire {
/**
* @var string
*
* @ORM\Column(name="firstName", type="string", length=64)
*/
private $firstName;
/**
* @var string
*
* @ORM\Column(name="lastName", type="string", length=64)
*/
private $lastName;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=32)
*/
private $email;
/**
* @var \DateTime
*
* @ORM\Column(name="birthday", type="date")
*/
private $birthday;
/**
* @var integer
*
* @ORM\Column(name="shoeSize", type="integer")
*/
private $shoeSize;
/**
* Set firstName
*
* @param string $firstName
*
* @return Questionnaire
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get firstName
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set lastName
*
* @param string $lastName
*
* @return Questionnaire
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get lastName
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set email
*
* @param string $email
*
* @return Questionnaire
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set birthday
*
* @param \DateTime $birthday
*
* @return Questionnaire
*/
public function setBirthday($birthday)
{
$this->birthday = $birthday;
return $this;
}
/**
* Get birthday
*
* @return \DateTime
*/
public function getBirthday()
{
return $this->birthday;
}
/**
* Set shoeSize
*
* @param integer $shoeSize
*
* @return Questionnaire
*/
public function setShoeSize($shoeSize)
{
$this->shoeSize = $shoeSize;
return $this;
}
/**
* Get shoeSize
*
* @return integer
*/
public function getShoeSize()
{
return $this->shoeSize;
}
}
/**
* SecondQuestions
*/
class SecondQuestions extends Questionnaire {
/**
* @var string
*
* @ORM\Column(name="favoriteIceCream", type="string", length=128)
*/
private $favoriteIceCream;
/**
* @var string
*
* @ORM\Column(name="favoriteSuperHero", type="string", length=32)
*/
private $favoriteSuperHero;
/**
* @var string
*
* @ORM\Column(name="favoriteMovieStar", type="string", length=64)
*/
private $favoriteMovieStar;
/**
* @var \DateTime
*
* @ORM\Column(name="endOfTheWorld", type="date")
*/
private $endOfTheWorld;
/**
* @var string
*
* @ORM\Column(name="superBowlWinner", type="string", length=32)
*/
private $superBowlWinner;
/**
* Set favoriteIceCream
*
* @param string $favoriteIceCream
*
* @return Questionnaire
*/
public function setFavoriteIceCream($favoriteIceCream)
{
$this->favoriteIceCream = $favoriteIceCream;
return $this;
}
/**
* Get favoriteIceCream
*
* @return string
*/
public function getFavoriteIceCream()
{
return $this->favoriteIceCream;
}
/**
* Set favoriteSuperHero
*
* @param string $favoriteSuperHero
*
* @return Questionnaire
*/
public function setFavoriteSuperHero($favoriteSuperHero)
{
$this->favoriteSuperHero = $favoriteSuperHero;
return $this;
}
/**
* Get favoriteSuperHero
*
* @return string
*/
public function getFavoriteSuperHero()
{
return $this->favoriteSuperHero;
}
/**
* Set favoriteMovieStar
*
* @param string $favoriteMovieStar
*
* @return Questionnaire
*/
public function setFavoriteMovieStar($favoriteMovieStar)
{
$this->favoriteMovieStar = $favoriteMovieStar;
return $this;
}
/**
* Get favoriteMovieStar
*
* @return string
*/
public function getFavoriteMovieStar()
{
return $this->favoriteMovieStar;
}
/**
* Set endOfTheWorld
*
* @param \DateTime $endOfTheWorld
*
* @return Questionnaire
*/
public function setEndOfTheWorld($endOfTheWorld)
{
$this->endOfTheWorld = $endOfTheWorld;
return $this;
}
/**
* Get endOfTheWorld
*
* @return \DateTime
*/
public function getEndOfTheWorld()
{
return $this->endOfTheWorld;
}
/**
* Set superBowlWinner
*
* @param string $superBowlWinner
*
* @return Questionnaire
*/
public function setSuperBowlWinner($superBowlWinner)
{
$this->superBowlWinner = $superBowlWinner;
return $this;
}
/**
* Get superBowlWinner
*
* @return string
*/
public function getSuperBowlWinner()
{
return $this->superBowlWinner;
}
}
Так что проблема в том, когда я пытаюсь создать объект дочернего класса (FirstQuestions или же SecondsQuestions) в методе контроллера Symfony отображает мне ошибку «500 — внутренняя ошибка сервера». Код контроллера с методом ниже:
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Questionnaire;
use AppBundle\Entity\FirstQuestions;
use AppBundle\Entity\SecondQuestions;
class TestController extends Controller
{
/**
* @Route("/test", name="test")
*/
public function indexAction(Request $request)
{
$item = new FirstQuestions(); // everything works well without this line
return new Response(
'ok'
);
}
}
Может быть, я делаю что-то не так или не сделал какой-либо важной аннотации. Может кто-нибудь мне помочь?
Это будет одна из тех раздражающих маленьких ошибок надзора — лишняя точка с запятой или что-то такое, что вы не ищете. Я создаю этот дополнительный ответ, чтобы я мог дать вам именно тот код, который я использую. Надеюсь, вы сможете вырезать и вставлять, заменять свои собственные файлы этим новым кодом, и он волшебным образом начнет работать.
Во-первых, чтобы доказать свою точку зрения, вот мой (модифицированный) вывод:
Veromo\Bundle\CoreBundle\Entity\FirstQuestions Object
(
[firstName:Veromo\Bundle\CoreBundle\Entity\FirstQuestions:private] =>
[lastName:Veromo\Bundle\CoreBundle\Entity\FirstQuestions:private] =>
[email:Veromo\Bundle\CoreBundle\Entity\FirstQuestions:private] =>
[birthday:Veromo\Bundle\CoreBundle\Entity\FirstQuestions:private] =>
[shoeSize:Veromo\Bundle\CoreBundle\Entity\FirstQuestions:private] =>
[id:Veromo\Bundle\CoreBundle\Entity\Questionnaire:private] =>
)
Что показывает, что все, что я делаю с тобой по-другому, — это использование пространств имен моей собственной среды разработки.
AppBundle \ Entity \ Questionnaire.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Questionnaire
*
* @ORM\Entity
* @ORM\Table(name="questionnaire")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"questionnaire"="Questionnaire", "firstquestions" = "FirstQuestions", "secondquestions" = "SecondQuestions"})
*/
abstract class Questionnaire {
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}
AppBundle \ Entity \ FirstQuestions.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* FirstQuestions
* @ORM\Entity()
*/
class FirstQuestions extends Questionnaire {
/**
* @var string
*
* @ORM\Column(name="firstName", type="string", length=64)
*/
private $firstName;
/**
* @var string
*
* @ORM\Column(name="lastName", type="string", length=64)
*/
private $lastName;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=32)
*/
private $email;
/**
* @var \DateTime
*
* @ORM\Column(name="birthday", type="date")
*/
private $birthday;
/**
* @var integer
*
* @ORM\Column(name="shoeSize", type="integer")
*/
private $shoeSize;
/**
* Set firstName
*
* @param string $firstName
*
* @return Questionnaire
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
return $this;
}
/**
* Get firstName
*
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Set lastName
*
* @param string $lastName
*
* @return Questionnaire
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
return $this;
}
/**
* Get lastName
*
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* Set email
*
* @param string $email
*
* @return Questionnaire
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set birthday
*
* @param \DateTime $birthday
*
* @return Questionnaire
*/
public function setBirthday($birthday)
{
$this->birthday = $birthday;
return $this;
}
/**
* Get birthday
*
* @return \DateTime
*/
public function getBirthday()
{
return $this->birthday;
}
/**
* Set shoeSize
*
* @param integer $shoeSize
*
* @return Questionnaire
*/
public function setShoeSize($shoeSize)
{
$this->shoeSize = $shoeSize;
return $this;
}
/**
* Get shoeSize
*
* @return integer
*/
public function getShoeSize()
{
return $this->shoeSize;
}
}
AppBundle \ Entity \ SecondQuestions.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* SecondQuestions
* @ORM\Entity()
*/
class SecondQuestions extends Questionnaire {
/**
* @var string
*
* @ORM\Column(name="favoriteIceCream", type="string", length=128)
*/
private $favoriteIceCream;
/**
* @var string
*
* @ORM\Column(name="favoriteSuperHero", type="string", length=32)
*/
private $favoriteSuperHero;
/**
* @var string
*
* @ORM\Column(name="favoriteMovieStar", type="string", length=64)
*/
private $favoriteMovieStar;
/**
* @var \DateTime
*
* @ORM\Column(name="endOfTheWorld", type="date")
*/
private $endOfTheWorld;
/**
* @var string
*
* @ORM\Column(name="superBowlWinner", type="string", length=32)
*/
private $superBowlWinner;
/**
* Set favoriteIceCream
*
* @param string $favoriteIceCream
*
* @return Questionnaire
*/
public function setFavoriteIceCream($favoriteIceCream)
{
$this->favoriteIceCream = $favoriteIceCream;
return $this;
}
/**
* Get favoriteIceCream
*
* @return string
*/
public function getFavoriteIceCream()
{
return $this->favoriteIceCream;
}
/**
* Set favoriteSuperHero
*
* @param string $favoriteSuperHero
*
* @return Questionnaire
*/
public function setFavoriteSuperHero($favoriteSuperHero)
{
$this->favoriteSuperHero = $favoriteSuperHero;
return $this;
}
/**
* Get favoriteSuperHero
*
* @return string
*/
public function getFavoriteSuperHero()
{
return $this->favoriteSuperHero;
}
/**
* Set favoriteMovieStar
*
* @param string $favoriteMovieStar
*
* @return Questionnaire
*/
public function setFavoriteMovieStar($favoriteMovieStar)
{
$this->favoriteMovieStar = $favoriteMovieStar;
return $this;
}
/**
* Get favoriteMovieStar
*
* @return string
*/
public function getFavoriteMovieStar()
{
return $this->favoriteMovieStar;
}
/**
* Set endOfTheWorld
*
* @param \DateTime $endOfTheWorld
*
* @return Questionnaire
*/
public function setEndOfTheWorld($endOfTheWorld)
{
$this->endOfTheWorld = $endOfTheWorld;
return $this;
}
/**
* Get endOfTheWorld
*
* @return \DateTime
*/
public function getEndOfTheWorld()
{
return $this->endOfTheWorld;
}
/**
* Set superBowlWinner
*
* @param string $superBowlWinner
*
* @return Questionnaire
*/
public function setSuperBowlWinner($superBowlWinner)
{
$this->superBowlWinner = $superBowlWinner;
return $this;
}
/**
* Get superBowlWinner
*
* @return string
*/
public function getSuperBowlWinner()
{
return $this->superBowlWinner;
}
}
AppBundle \ Controller \ TestController.php
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Questionnaire;
use AppBundle\Entity\FirstQuestions;
use AppBundle\Entity\SecondQuestions;
class TestController extends Controller
{
/**
* @Route("/test",name="test")
*/
public function indexAction( Request $request )
{
$item = new FirstQuestions();
return new Response(
'<pre>'.print_r( $item, true ).'</pre>'
);
}
}
И просто чтобы быть уверенным …
Приложение \ Config \ routing.yml
test:
resource: "@AppBundle/Controller/TestController.php"type: annotation
Это ДОЛЖНО быть какой-то глупой, раздражающей маленькой ошибкой, которую никто не ищет.
Надеюсь это поможет …
ВСЕ классы сущностей, которые являются частью иерархии сопоставленных сущностей, должны быть указаны в @DiscriminatorMap. Так что да, ваша аннотация неверна.
РЕДАКТИРОВАТЬ
У вас есть другая ошибка аннотаций — ни один из ваших подклассов не имеет аннотации @Entity:
/**
* FirstQuestions
* @ORM\Entity()
*/
class FirstQuestions extends Questionnaire {
/**
* SecondQuestions
* @ORM\Entity()
*/
class SecondQuestions extends Questionnaire {
После исправления я смог использовать инструмент обновления схемы Doctrine для построения таблиц и успешно создал FirstQuestions объект.