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

时间:2016-01-13 12:09:56

标签: php symfony doctrine-orm

在控制器的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();
    }

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

Doctrine Entities用作POPO(Plain Old PHP Objects)。要实现正确扩展,您需要使用MappedSuperClass这里是example