先决条件:
-
PHP 7.1.8
-
Symfony 3.3.9
-
Doctrine 2.6.x-dev
我想知道是否可以覆盖从特征中获取的属性关联映射的 inversedBy
属性 .
我用作具体用户实体占位符的接口:
ReusableBundle\ModelEntrantInterface.php
interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
- 以下架构工作正常(需要创建实现
EntrantInterface
的User
实体以及_1773123中从这些抽象类派生的所有其他实体):
ReusableBundle\Entity\Entry.php
/**
* @ORM\MappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="entries")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
ReusableBundle\Entity\Timestamp.php
/**
* @ORM\MappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface", inversedBy="timestamps")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
并结合使用 EntranInterface
类似结构的更多实体
- 这就是我想要实现的目标 -
UserAwareTrait
可以跨多个实体重复使用:
ReusableBundle\Entity\Traits\UserAwareTrait.php
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORM\ManyToOne(targetEntity="ReusableBundle\Model\EntrantInterface")
* @ORM\JoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
在Doctrine 2.6中,如果我使用超类并想要覆盖它的属性,我会这样做:
/**
* @ORM\MappedSuperclass
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride({name="property", inversedBy="entities"})
* })
*/
abstract class Entity extends SuperEntity
{
// code...
}
但是,如果我希望该实体使用 UserAwareTrait
并覆盖属性的关联映射...
/**
* @ORM\MappedSuperclass
* @ORM\AssociationOverrides({
* @ORM\AssociationOverride({name="user", inversedBy="entries"})
* })
*/
abstract class Entry
{
use UserAwareTrait;
// code...
}
...并运行 php bin/console doctrine:schema:validate
我在控制台中看到此错误:
[Doctrine \ ORM \ Mapping \ MappingException]类'ReusableBundle \ Entity \ Entry'的名为'user'的字段覆盖无效 .
有没有可以遵循的解决方法来达到预期的效果?
-
使用特征存储共享属性
-
覆盖使用该特征的类中的assotiation mapping或(可能)属性映射
3 回答
TL;DR 您应该将访问修改器从
protected
更改为private
. 不要忘记,您将无法直接操作子类中的私有属性,并且需要一个getter .由于
AnnotationDriver
中的错误(我相信或行为的怪癖)而出现异常 .它会跳过
MappedSuperclass
的所有非私有属性,让它们在子类解析上组合元数据 . 但是当涉及到覆盖驱动程序尝试在MappedSuperclass
级别执行时,它不记得该属性被跳过,无法在元数据中找到它并引发异常 .我在the issue做了详细解释 . 您还可以找到突出显示案例的单元测试的链接 .
您必须在自己的代码中尝试这一点才能看到,但它可以实现.177144可能 .
作为一个实验,我重写了一个类中的特征,然后使用
class_uses()
http://php.net/manual/en/function.class-uses.php检查了特征这输出:
你在这里可以看到https://3v4l.org/Vin2H
但是,Doctrine Annotations仍然可以从特性而非被覆盖的方法中获取DocBlock,这就是为什么我不能给你一个明确的答案 . 你只需要尝试一下,看看!
我有一个类似的问题,并通过覆盖它自己的属性来解决它: