在Doctrine 2.6中覆盖特征属性的关联映射
先决条件:
我想知道是否可以重写属性关联映射的inversedBy
属性,该属性取自特征。
我用作具体用户实体占位符的接口:
ReusableBundle ModelEntrantInterface.php
interface EntrantInterface
{
public function getEmail();
public function getFirstName();
public function getLastName();
}
EntrantInterface
User
实体以及派生自AppBundle
这些抽象类的所有其他实体): ReusableBundle 实体 Entry.php
/**
* @ORMMappedSuperclass
*/
abstract class Entry
{
/**
* @var EntrantInterface
*
* @ORMManyToOne(targetEntity="ReusableBundleModelEntrantInterface", inversedBy="entries")
* @ORMJoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
ReusableBundle 实体 Timestamp.php
/**
* @ORMMappedSuperclass
*/
abstract class Timestamp
{
/**
* @var EntrantInterface
*
* @ORMManyToOne(targetEntity="ReusableBundleModelEntrantInterface", inversedBy="timestamps")
* @ORMJoinColumn(name="user_id")
*/
protected $user;
// getters/setters...
}
还有更多使用EntranInterface
具有相似结构的实体
UserAwareTrait
可以跨几个实体重用: ReusableBundle 实体特征 UserAwareTrait.php
trait UserAwareTrait
{
/**
* @var EntrantInterface
*
* @ORMManyToOne(targetEntity="ReusableBundleModelEntrantInterface")
* @ORMJoinColumn(name="user_id")
*/
protected $user;
// getter/setter...
}
在Doctrine 2.6中,如果我会使用超类,并希望覆盖它的属性,我会这样做:
/**
* @ORMMappedSuperclass
* @ORMAssociationOverrides({
* @ORMAssociationOverride({name="property", inversedBy="entities"})
* })
*/
abstract class Entity extends SuperEntity
{
// code...
}
但是如果我希望该实体使用UserAwareTrait
并覆盖属性的关联映射......
/**
* @ORMMappedSuperclass
* @ORMAssociationOverrides({
* @ORMAssociationOverride({name="user", inversedBy="entries"})
* })
*/
abstract class Entry
{
use UserAwareTrait;
// code...
}
...并运行php bin/console doctrine:schema:validate
我在控制台中看到这个错误:
[学说 ORM 映射 MappingException]
对于'ReusableBundle Entity Entry'类,名为'user'的字段覆盖无效。
有没有一种解决方法可以实现预期的效果?
使用trait来存储共享属性
覆盖使用该特征的类中的assotiation映射或(可能)属性映射
TL; DR您应该将访问修改从protected
更改为private
。 不要忘记,你将无法直接操作子类中的私有属性,并需要一个getter。
这个异常是由于AnnotationDriver
的错误(我相信,或者是一个怪癖)而出现的。
foreach ($class->getProperties() as $property) {
if ($metadata->isMappedSuperclass && ! $property->isPrivate()
||
...) {
continue;
}
它跳过MappedSuperclass
所有非私有属性,让它们在子类解析中MappedSuperclass
元数据。 但是当涉及重写驱动程序试图在MappedSuperclass
级别执行它时,它不记得该属性被跳过,无法在元数据中找到它并引发异常。
我在这个问题上做了详细的解释。 你也可以在那里找到单元测试的链接来突出显示案例。
你必须在你自己的代码中试试看,但它可能是可能的。
作为一个实验,我重写了一个类的特征,然后使用class_uses()
检查特征http://php.net/manual/en/function.class-uses.php
<?php
trait CanWhatever
{
public function doStuff()
{
return 'result!';
}
}
class X
{
use CanWhatever;
public function doStuff()
{
return 'overridden!';
}
}
$x = new X();
echo $x->doStuff();
echo "n$x has ";
echo (class_uses($x, 'CanWhatever')) ? 'the trait' : 'no trait';
这输出:
overridden!
$x has the trait
你可以在这里看到https://3v4l.org/Vin2H
然而,Doctrine Annotations仍然可能会从适当的特性中挑选出DocBlock,而不是重写的方法,这就是为什么我不能给你一个确定的答案。 你只需要尝试一下,看看!
我有一个类似的问题,并通过覆盖它自己的属性来解决它:
use UserAwareTrait;
/**
* @var EntrantInterface
* @ORMManyToOne(targetEntity="ReusableBundleModelEntrantInterface"inversedBy="entries")
*/
protected $user;
链接地址: http://www.djcxy.com/p/69387.html
上一篇: Override association mapping of a trait property in Doctrine 2.6