我试图在Doctrine 2中完成基本继承,但我遇到了几个主要问题。这样的任务不应该这么复杂。我们谈正事吧..。
我有三门课,BaseFoodType,饮料和零食。我的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;
}
build和Snack都继承了这个基类,但是当我试图使用“生成:实体”命令构建我的实体时,我遇到了许多问题。首先,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;
}
第二,我犯了一个致命的错误:
致命错误:第197行C:\xampp\htdocs\MySite\src\MySite\MainBundle\Entity\Drink.php中对MySite\MainBundle\Entity\ line::$预算的访问级别必须是公共的(如MySite\MainBundle\Entity\BaseFoodType类中的那样)
我可能会将生成的属性公之于众,并在我的路上,但同样,这违背了继承的目的!
提前感谢您的任何见解。
发布于 2014-02-11 02:52:55
理论提供了一种方法来指定生成字段的可见性。不管是受保护的还是私人的。默认值是私有的。
问题是调用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
{
}
生成数据类后,如下所示:
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
发布于 2013-07-01 16:56:26
抛出此异常是因为BaseFoodType::budget
是公共属性,doctrine:generate:entities
在饮料/ Snack类中创建了私有属性,扩展BaseFoodType (这是不正确的,但到目前为止命令的工作方式)。
子类中的属性可见性只能是相同的级别或更多的自由度(私有->保护的->公共),但从来没有更多的限制。
doctrine:generate:entities在生成getter/setter时没有考虑超类的公共属性,因为带有公共属性的实现是不标准的。
因此,您必须手动调整生成的类。
我建议将私有/受保护的属性与getters和setter结合使用。
https://stackoverflow.com/questions/17408757
复制相似问题