使用Doctrine2在Symfony2中扩展实体

13
我在使用Symfony2和Doctrine2作为ORM时,遇到了一个问题,即如何适当地跨bundle扩展实体。我希望能够使用UserBundle在没有BlogBundle的项目中,并且在具有User Bundle的项目中始终使用BlogBundle。 这可以通过将UserBundle\Entity\User对象从BlogBundle中扩展并向其中添加方法和属性来实现。但这会导致问题,因为两个实体都尝试映射并创建相同的表。尝试使用ResolveTargetEntityListener功能,但这与Mapped Superclas、STI和CTI都会强制使UserBundle依赖于BlogBundle。
@ORM\Table(name="app_user")
@ORM\Entity
class User implements UserInterface
{
    ...
}

博客捆绑实体帖子。

@ORM\Table(name="app_post")
@ORM\Entity
class Post
{
    ...

    @ORM\Column(name="author_id", type="integer")
    protected $author_id;

    @ORM\ManyToOne(targetEntity="\App\BlogBundle\Entity\User", inversedBy="posts")
    @ORM\JoinColumn(name="author_id", referencedColumnName="id")
    protected $author;
}

BlogBundle\Entity\User

use App\UserBundle\Entity\User as BaseUser
@ORM\Entity
@ORM\table(name="app_user")
class User extends BaseUser
{
    ....

    @ORM\OneToMany(targetEntity="App\BlogBundle\Entity\Post", mappedBy="author")
    protected $posts;

    public function __construct()
    {
        parent::_construct();

        $this->posts = new \Doctrine\Common\Collections\ArrayCollection();
    }

    .... 
    /* Getters & Setters, nothing that defines @ORM\Column, nothing persisted */
}

这个方案是可行的,但问题是我在项目中将两个实体映射到同一张表中。扩展对象没有从其父级获取@ORM\Table(name="app_user") ,因此必须在BlogBundle\Entity\User中定义该表。如果没有,在控制器中对此对象的任何引用都将无法访问数据库。由于扩展对象没有持久化任何内容,除了当我尝试从控制台更新数据库模式时会出错。

我可以使用单向关联,但这会限制我从控制器内部访问数据的方式。


我知道这是一个非常老的问题;但你解决了吗?我也面临着同样的问题,努力寻找任何可行的解决方案。 - bigstylee
2个回答

8
您可以查看此链接以了解有关继承的信息:http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance 您必须在UserBundle\Entity\User中声明:
/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"baseuser" = "UserBundle\Entity\User", "blogUser" = "BlogBundle\Entity\User"})
 */
class User implements UserInterface
{
    ...
}

And BlogBundle\Entity\User

use App\UserBundle\Entity\User as BaseUser;
/**
 * @ORM\Entity
 */
class User extends BaseUser
{
    ....
}

祝你好运!


1
我认为这不是一个令人满意的解决方案,因为在@DiscriminatorMap中,UserBundle对BlogBundle有引用。我对一种解决方案感兴趣,其中UserBundle根本没有对BlogBundle的引用/依赖。 - aimfeld

0

我认为你可能会觉得这个Bundle很有趣:

https://github.com/mmoreram/SimpleDoctrineMapping

它允许您通过参数定义映射实体的文件,从而允许覆盖通用包中的每个实体。

例如:

parameters:

    #
    # Mapping information
    #
    test_bundle.entity.user.class: "TestBundle\Entity\User"
    test_bundle.entity.user.mapping_file_path: "@TestBundle/Mapping/Class.orm.yml"
    test_bundle.entity.user.entity_manager: default
    test_bundle.entity.user.enable: true

我唯一看到的缺点是,因为您禁用了自动映射,您必须以相同的方式定义所有下一个实体。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接