【问题标题】:Symfony2 After form submit entity not extended on base entitySymfony2表单提交实体后未在基础实体上扩展
【发布时间】:2016-01-13 12:09:55
【问题描述】:

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

【问题讨论】:

    标签: php symfony doctrine-orm


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多