Php 覆盖条令2.6中特征属性的关联映射
先决条件:Php 覆盖条令2.6中特征属性的关联映射,php,symfony,doctrine-orm,doctrine,symfony-3.3,Php,Symfony,Doctrine Orm,Doctrine,Symfony 3.3,先决条件: PHP7.1.8 Symfony 3.3.9 条令2.6.x-dev 我想知道是否有可能覆盖属性关联映射的inversedBy属性,该属性取自特征 我用作具体用户实体占位符的界面: ReusableBundle\modelnentranterface.php interface EntrantInterface { public function getEmail(); public function getFirstName(); public fu
- PHP7.1.8
- Symfony 3.3.9
- 条令2.6.x-dev
inversedBy
属性,该属性取自特征
我用作具体用户实体占位符的界面:
ReusableBundle\modelnentranterface.php
interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
/**
* @ORM\MappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
/**
* @ORM\MappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
entranterface
的User
实体以及从AppBundle
中的这些抽象类派生的所有其他实体):interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
/**
* @ORM\MappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
/**
* @ORM\MappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
ReusableBundle\Entity\Timestamp.php
interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
/**
* @ORM\MappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
/**
* @ORM\MappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
并使用entranterface
userawaretrit
可以跨多个实体重用:interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
/**
* @ORM\MappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
/**
* @ORM\MappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
在原则2.6中,如果我想使用超类并覆盖它的属性,我会这样做:
/**
* @ORM\MappedSuperclass
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride({name="property", inversedBy="entities"})
* })
*/
abstract class Entity extends SuperEntity
{
// code...
}
但是,如果我希望该实体使用userawaretrit
并覆盖属性的关联映射
/**
* @ORM\MappedSuperclass
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride({name="user", inversedBy="entries"})
* })
*/
abstract class Entry
{
use UserAwareTrait;
// code...
}
。。。然后运行php-bin/console-doctor:schema:validate
我在控制台中看到这个错误:
[条令\ORM\Mapping\MappingException]类“ReusableBundle\Entity\Entry”的名为“user”的字段重写无效 是否有一个变通方法,我可以遵循,以达到预期的结果
您必须在自己的代码中尝试这一点才能看到,但这是可能的 作为实验,我重写了类中的一个特征,然后使用
class\u uses()
你可以在这里看到
然而,条令注释仍然可能从trait本身而不是覆盖的方法中获取DocBlock,这就是为什么我不能给您一个明确的答案。你只需要试试看 TL;DR您应该将访问修改器从
受保护
更改为专用
。不要忘记,您将无法直接操作子类中的私有属性,并且需要一个getter
出现异常的原因是AnnotationDriver
中的错误(我相信,或行为异常)
foreach ($class->getProperties() as $property) {
if ($metadata->isMappedSuperclass && ! $property->isPrivate()
||
...) {
continue;
}
它跳过了MappedSuperclass
的所有非私有属性,让它们在子类解析时组成元数据。但是,当涉及到重写时,驱动程序尝试在MappedSuperclass
级别执行此操作,它不记得该属性已被跳过,在元数据中找不到该属性并引发异常
我在会议上作了详细的解释。您还可以在这里找到突出显示该案例的单元测试的链接 我遇到了一个类似的问题,并通过重写其自身的属性来解决它:
use UserAwareTrait;
/**
* @var EntrantInterface
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface"inversedBy="entries")
*/
protected $user;
谢谢你的回答,这不是我需要的。我不想重写一个方法(我只需要在每个类中定义它,然后分别进行注释,这正是我希望避免的)。在方法体中没有什么可以重写的,只有getter和setter。我有一个类似的实现,但在我的例子中,使用这个特性的类不是
MappedSuperclass
。您是否尝试过删除抽象类条目上的@ORM\MappedSuperclass
行?更重要的是:您尝试在不指定关系的情况下重写a关系(在本例中为ManyToOne
。尝试:@ORM\AssociationOverrides({@ORM\AssociationOverride(name=“user”,ManyToOne=@ORM\ManyToOne(targetEntity=“ReusableBundle\Model\entranterface”,inversedBy=“entities”))
。在最后一个代码块中,它是inversedBy=“entries”
,与原始代码相同,在第二个代码块中,它是inversedBy=“entities”
…请仔细阅读,我想在多个实体中重复使用特征,因此没有机会在特征中覆盖它,inversedBy必须为每个实体具有不同的值是的,我的回答是覆盖每个实体中的特征属性,以设置适当的inversedBy