我正在尝试在Doctrine 2中完成BASIC继承,但我遇到了几个主要问题。这样的任务不应该那么复杂。让我们开始做生意......
我有三个类,BaseFoodType,Drink和Snack。我的BaseFoodType具有以下类定义:
/** @ORM\MappedSuperclass */
class BaseFoodType {
/**
* @ORM\Column(type="integer", length=7)
*/
public $budget = 0;
}
遵循学说网站上的继承说明:http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html
以下是生成实体之前子类的样子:
namespace MySite\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* MySite\MainBundle\Entity\EventDrink
*
* @ORM\Table(name="drink")
* @ORM\Entity
*/
class Drink extends BaseFoodType {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="integer", length=5, nullable=true)
*/
public $people_count;
}
Drink和Snack都继承自这个基类,但是当我尝试使用doctrine:generate:entities命令构建我的实体时,我遇到了很多问题。首先,Symfony在每个子类中插入一个私有的“预算”属性,以及getter和setter(这是对目的的继承)
/**
* @var integer
*/
private $budget;
/**
* Set budget
*
* @param integer $budget
*/
public function setBudget($budget)
{
$this->budget = $budget;
return $this;
}
/**
* Get budget
*
* @return integer
*/
public function getBudget()
{
return $this->budget;
}
其次,我遇到致命错误:
致命错误:MySite \ MainBundle \ Entity \ Drink :: $ budget的访问级别 必须是公共的(如在MySite \ MainBundle \ Entity \ BaseFoodType类中) C:\ xampp \ htdocs \ MySite \ src \ MySite \ MainBundle \ Entity \ Drink.php在线 197
我可能会将生成的属性设为公开并且在我的路上,但同样,这会破坏继承的目的!
提前感谢任何见解。
答案 0 :(得分:3)
Doctrine提供了指定生成字段可见性的方法。受保护或私人。默认为私有。
问题是调用Doctrine的Symfony命令无法改变它。
创建自己的标准Symfony命令的子类将允许您更好地控制生成过程。这可能会帮助你。
namespace Foo\Bundle\FooBundle\Command;
use Doctrine\Bundle\DoctrineBundle\Command as DC;
use Doctrine\ORM\Tools\EntityGenerator;
class GenerateEntitiesDoctrineCommand extends DC\GenerateEntitiesDoctrineCommand
{
protected function configure()
{
parent::configure();
$this->setName('foo:generate:entities');
}
/**
* get a doctrine entity generator
*
* @return EntityGenerator
*/
protected function getEntityGenerator()
{
$entityGenerator = new EntityGenerator();
$entityGenerator->setGenerateAnnotations(true);
$entityGenerator->setGenerateStubMethods(true);
$entityGenerator->setRegenerateEntityIfExists(false);
$entityGenerator->setUpdateEntityIfExists(true);
$entityGenerator->setNumSpaces(4);
$entityGenerator->setAnnotationPrefix('ORM\\');
$entityGenerator->setFieldVisibility($entityGenerator::FIELD_VISIBLE_PROTECTED);
return $entityGenerator;
}
}
这有两件事。它将属性可见性设置为受保护。这可以防止php错误。
$entityGenerator->setFieldVisibility($entityGenerator::FIELD_VISIBLE_PROTECTED);
它还将映射超类中的注释复制到实体类中。
$entityGenerator->setGenerateAnnotations(true);
这是一些示例代码,其中属性从基类继承,并且它们的可见性和注释正确地复制到继承类中
/** @ORM\MappedSuperclass */
class DataSuper {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Campaign", inversedBy="data")
* @ORM\JoinColumn(name="campaign_id", referencedColumnName="id")
* @Exclude
*/
protected $campaign;
/**
* @ORM\Column(type="text", nullable=true, name="data")
*/
protected $data;
/**
* @ORM\Column(type="datetime")
*/
protected $createdDate;
}
/**
* @ORM\Entity(repositoryClass="Foo\Bundle\FooBundle\Entity\DataRepository")
* @ORM\Table(name="data")
* @ExclusionPolicy("none")
*/
class Data extends DataSuper
{
}
生成后,Data类看起来像:
class Data extends DataSuper
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="data", type="text", precision=0, scale=0, nullable=true, unique=false)
*/
protected $data;
/**
* @var \DateTime
*
* @ORM\Column(name="createdDate", type="datetime", precision=0, scale=0, nullable=false, unique=false)
*/
protected $createdDate;
/**
* @var \Foo\Bundle\FooBundle\Entity\Campaign
*
* @ORM\ManyToOne(targetEntity="Foo\Bundle\FooBundle\Entity\Campaign", inversedBy="data")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="campaign_id", referencedColumnName="id", nullable=true)
* })
*/
protected $campaign;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set data
*
* @param string $data
* @return Data
*/
public function setData($data)
{
$this->data = $data;
return $this;
}
/**
* Get data
*
* @return string
*/
public function getData()
{
return $this->data;
}
/**
* Set createdDate
*
* @param \DateTime $createdDate
* @return Data
*/
public function setCreatedDate($createdDate)
{
$this->createdDate = $createdDate;
return $this;
}
/**
* Get createdDate
*
* @return \DateTime
*/
public function getCreatedDate()
{
return $this->createdDate;
}
/**
* Set campaign
*
* @param \Foo\Bundle\FooBundle\Entity\Campaign $campaign
* @return Data
*/
public function setCampaign(\Foo\Bundle\FooBundle\Entity\Campaign $campaign = null)
{
$this->campaign = $campaign;
return $this;
}
/**
* Get campaign
*
* @return \Foo\Bundle\FooBundle\Entity\Campaign
*/
public function getCampaign()
{
return $this->campaign;
}
}
表格结构正确无误:
php app/console doctrine:schema:update --force
答案 1 :(得分:0)
由于BaseFoodType::budget
是公开属性而doctrine:generate:entities
在您的Drink / Snack类中创建了私有属性,因此抛出了异常,因为它扩展了BaseFoodType (这不正确,但现在命令的工作方式)。
子类中的属性可见性只能是相同级别或更多自由(私有 - > protected - > public),但绝不会更具限制性。
生成getter / setter时,doctrine:generate:entities没有考虑超类的公共属性,因为具有公共属性的实现是非标准的。
因此,您必须手动调整生成的类。
我建议使用私有/受保护的属性与getter& setter方法。