Symfony2表单提交后实体未在基本实体上扩展


Symfony2 After form submit entity not extended on base entity

在控制器的editAction方法中,我试图编辑类表继承中的现有实体。

但在表格提交后,我收到错误:

既不是属性"id"也不是其中一个方法"addId()"/"removeId()"、"setId()、"id()"、"__set()"或"__call()"在类"AdBundle''Entity''AdFlat"中存在并具有公共访问权限。

为什么AdFlat实体没有扩展AdBase实体?

基础实体:

<?php
namespace AdBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use Symfony'Component'Validator'Constraints as Assert;
/**
 * AdBase
 *
 * @ORM'Table(name="ad_base")
 * @ORM'Entity(repositoryClass="AdBundle'Repository'AdBaseRepository")
 * @ORM'HasLifecycleCallbacks()
 * @ORM'InheritanceType("JOINED")
 * @ORM'DiscriminatorColumn(name="discr", type="string")
 * @ORM'DiscriminatorMap({
    "flat" = "AdFlat"
 *     })
 */
abstract class AdBase
{
    /**
     * @var int
     *
     * @ORM'Column(name="id", type="integer")
     * @ORM'Id
     * @ORM'GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @var string
     *
     * @ORM'Column(name="author", type="string", length=255)
     */
    private $author;
    /**
     * @ORM'ManyToOne(targetEntity="AdBundle'Entity'AdCategory")
     */
    private $category;
    /**
     * @ORM'Column(type="string")
     * @Assert'NotBlank(message="Field Location should not be blank")
     */
    private $location;
    /**
     * @var string
     *
     * @ORM'Column(name="title", type="string", length=255)
     * @Assert'NotBlank(message="Not specified Title")
     */
    private $title;
    /**
     * @var string
     *
     * @ORM'Column(name="description", type="text", nullable=true)
     * @Assert'NotBlank(message="Not specified Description")
     */
    private $description;
    /**
     * @ORM'OneToMany(targetEntity="AdBundle'Entity'AdPhoto", mappedBy="ad")
     */
    private $photos;
    /**
     * @ORM'Column(type="float")
     * @Assert'NotBlank()
     */
    private $price;
    /**
     * @ORM'ManyToOne(targetEntity="AdBundle'Entity'AdPriceType")
     */
    private $priceType;
    /**
     * @var 'DateTime
     *
     * @ORM'Column(name="createdAt", type="datetime")
     */
    private $createdAt;
    /**
     * @var string
     *
     * @ORM'Column(name="updatedAt", type="datetime")
     */
    private $updatedAt;
    /**
     * @var bool
     *
     * @ORM'Column(name="visible", type="boolean")
     */
    private $visible = false;

    /**
     * @ORM'Column(type="boolean")
     */
    private $active = true;
    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
    /**
     * Set author
     *
     * @param string $author
     *
     * @return AdBase
     */
    public function setAuthor($author)
    {
        $this->author = $author;
        return $this;
    }
    /**
     * Get author
     *
     * @return string
     */
    public function getAuthor()
    {
        return $this->author;
    }
    /**
     * @return mixed
     */
    public function getCategory()
    {
        return $this->category;
    }
    /**
     * @param mixed $category
     */
    public function setCategory($category)
    {
        $this->category = $category;
    }
    /**
     * @return mixed
     */
    public function getLocation()
    {
        return $this->location;
    }
    /**
     * @param mixed $location
     */
    public function setLocation($location)
    {
        $this->location = $location;
    }
    /**
     * Set title
     *
     * @param string $title
     *
     * @return AdBase
     */
    public function setTitle($title)
    {
        $this->title = $title;
        return $this;
    }
    /**
     * Get title
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }
    /**
     * Set description
     *
     * @param string $description
     *
     * @return AdBase
     */
    public function setDescription($description)
    {
        $this->description = $description;
        return $this;
    }
    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }
    /**
     * Set photos
     *
     * @param string $photos
     *
     * @return AdBase
     */
    public function setPhotos($photos)
    {
        $this->photos = $photos;
        return $this;
    }
    /**
     * Get photos
     *
     * @return string
     */
    public function getPhotos()
    {
        return $this->photos;
    }
    /**
     * @return mixed
     */
    public function getPrice()
    {
        return $this->price;
    }
    /**
     * @param mixed $price
     */
    public function setPrice($price)
    {
        $this->price = $price;
    }
    /**
     * @return mixed
     */
    public function getPriceType()
    {
        return $this->priceType;
    }
    /**
     * @param mixed $priceType
     */
    public function setPriceType($priceType)
    {
        $this->priceType = $priceType;
    }
    /**
     * Set createdAt
     *
     * @param 'DateTime $createdAt
     *
     * @return AdBase
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;
        return $this;
    }
    /**
     * Get createdAt
     *
     * @return 'DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }
    /**
     * Set updatedAt
     *
     * @param string $updatedAt
     *
     * @return AdBase
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;
        return $this;
    }
    /**
     * Get updatedAt
     *
     * @return string
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }
    /**
     * Set visible
     *
     * @param boolean $visible
     *
     * @return AdBase
     */
    public function setVisible($visible)
    {
        $this->visible = $visible;
        return $this;
    }
    /**
     * Get visible
     *
     * @return bool
     */
    public function getVisible()
    {
        return $this->visible;
    }
    /**
     * @return mixed
     */
    public function getActive()
    {
        return $this->active;
    }
    /**
     * @param mixed $active
     */
    public function setActive($active)
    {
        $this->active = $active;
    }
    /**
     * @ORM'PrePersist()
     */
    public function prePersist()
    {
        $this->author = 'voodoo';
        $this->createdAt = new 'DateTime('now', new 'DateTimeZone('UTC'));
        $this->updatedAt = new 'DateTime('now', new 'DateTimeZone('UTC'));
        $this->location = 'Donetsk';
    }
    /**
     * @ORM'PreUpdate()
     */
    public function preUpdate()
    {
        $this->updatedAt = new 'DateTime('now', new 'DateTimeZone('UTC'));
    }
}

扩展实体:

<?php
namespace AdBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use Symfony'Component'Validator'Constraints as Assert;
/**
 * AdFlat
 *
 * @ORM'Table(name="ad_flat")
 * @ORM'Entity(repositoryClass="AdBundle'Repository'AdFlatRepository")
 */
class AdFlat extends AdBase
{
    /**
     * @var integer
     *
     * @ORM'Column(type="integer")
     * @Assert'NotBlank(message="ad_flat.rooms.not_blank")
     */
    private $rooms;
    /**
     * @var float
     *
     * @ORM'Column(name="square", type="float", nullable=true)
     */
    private $square;
    /**
     * @var float
     *
     * @ORM'Column(name="liveSquare", type="float", nullable=true)
     */
    private $liveSquare;
    /**
     * @var float
     *
     * @ORM'Column(type="float", nullable=true)
     */
    private $kitchenSquare;
    /**
     * @var int
     *
     * @ORM'Column(name="floor", type="integer")
     */
    private $floor;
    /**
     * @var int
     *
     * @ORM'Column(name="floors", type="integer")
     */
    private $floors;
    /**
     * @var string
     *
     * @ORM'ManyToOne(targetEntity="AdBundle'Entity'AdWallType")
     */
    private $wallType;
    /**
     * @ORM'ManyToOne(targetEntity="AdBundle'Entity'AdWCType")
     */
    private $wcType;
    /**
     * @return mixed
     */
    public function getRooms()
    {
        return $this->rooms;
    }
    /**
     * @param mixed $rooms
     */
    public function setRooms($rooms)
    {
        $this->rooms = $rooms;
    }
    /**
     * Set square
     *
     * @param float $square
     *
     * @return AdFlat
     */
    public function setSquare($square)
    {
        $this->square = $square;
        return $this;
    }
    /**
     * Get square
     *
     * @return float
     */
    public function getSquare()
    {
        return $this->square;
    }
    /**
     * Set liveSquare
     *
     * @param float $liveSquare
     *
     * @return AdFlat
     */
    public function setLiveSquare($liveSquare)
    {
        $this->liveSquare = $liveSquare;
        return $this;
    }
    /**
     * Get liveSquare
     *
     * @return float
     */
    public function getLiveSquare()
    {
        return $this->liveSquare;
    }
    /**
     * @return float
     */
    public function getKitchenSquare()
    {
        return $this->kitchenSquare;
    }
    /**
     * @param float $kitchenSquare
     */
    public function setKitchenSquare($kitchenSquare)
    {
        $this->kitchenSquare = $kitchenSquare;
    }
    /**
     * Set floor
     *
     * @param integer $floor
     *
     * @return AdFlat
     */
    public function setFloor($floor)
    {
        $this->floor = $floor;
        return $this;
    }
    /**
     * Get floor
     *
     * @return int
     */
    public function getFloor()
    {
        return $this->floor;
    }
    /**
     * Set floors
     *
     * @param integer $floors
     *
     * @return AdFlat
     */
    public function setFloors($floors)
    {
        $this->floors = $floors;
        return $this;
    }
    /**
     * Get floors
     *
     * @return int
     */
    public function getFloors()
    {
        return $this->floors;
    }
    /**
     * Set wallType
     *
     * @param string $wallType
     *
     * @return AdFlat
     */
    public function setWallType($wallType)
    {
        $this->wallType = $wallType;
        return $this;
    }
    /**
     * Get wallType
     *
     * @return string
     */
    public function getWallType()
    {
        return $this->wallType;
    }
    /**
     * Set wcType
     *
     * @param string $wcType
     *
     * @return AdFlat
     */
    public function setWcType($wcType)
    {
        $this->wcType = $wcType;
        return $this;
    }
    /**
     * Get wcType
     *
     * @return string
     */
    public function getWcType()
    {
        return $this->wcType;
    }
}

控制器内:

public function editAction(Request $request)
    {
        $adId = $request->get('id');
        if (!$adId) {
            return $this->renderError('Unknown Ad');
        }
        $adEntity = $this->getDoctrine()->getRepository('AdBundle:AdBase')->find($adId);
        if (null === $adEntity) {
            return $this->renderError('Unknown Ad');
        }
        $reflection = new 'ReflectionClass($adEntity);
        $adForm = $this->getForm($reflection->getShortName());
        $form = $this->createForm($adForm, $adEntity);
        $form->handleRequest($request);
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($adEntity);
            $em->flush();
            return $this->redirectToRoute('ad_bundle_ad_view', array(
                'id' => $adEntity->getId()
            ));
        }
        return $this->render('AdBundle:Ad:edit-ad-flat.html.twig', array(
            'form' => $form->createView()
        ));
    }
    private function renderError($message = '')
    {
        return $this->render('::error.html.twig', array(
            'error' => $message
        ));
    }
    private function getEntity($className)
    {
        $entityName = 'AdBundle'Entity''' . $className;
        return new $entityName();
    }
    private function getForm($className)
    {
        $formName = 'AdBundle'Form'Type''' . $className . 'Type';
        return new $formName();
    }

错误消息只是指出您缺少设置实体的$id属性的方法。它不会告诉你任何关于类没有扩展基类的信息。但是,基类只为$id属性定义了一个getter方法,而没有定义setter方法。

条令实体作为POPO(普通的旧PHP对象)工作。为了实现正确的扩展,您需要使用MappedSuperClass,这里有一个示例