Symfony2中使用Doctrine注释的多个JoinColumns?

时间:2013-03-11 17:08:16

标签: symfony join doctrine-orm annotations

问题在于:

具有属性RoutingobjectId的班级objectTypeobjectId是一个int,objectType是一个字符串。这样做的原因是允许同一个表保存不同类型的路由数据。例如,ProductsDepartmentBrand的路由。因此,objectTypeobjectId的组合是我的JoinColumn。

如何与Doctrine2建立这样的双向关系?我看了一下继承的关系,但没有一个概念似乎是我正在寻找的。

我可以在数据库中创建一些视图,只有几个不同的路由实体,但这似乎不是最好的路径。

以下是我的实体DepartmentProductBrand

../Entity/Department.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="departments")
 */
class Department implements DescribableInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="status", type="string", length=1)
     */
    private $status;

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
...

../Entity/Product.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="products")
 */
class Product implements DescribableInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="status", type="string", length=1)
     */
    private $status;

    /**
     * @ORM\Column(name="product_code", type="string", length=100, nullable=true)
     */
    private $productCode = '';

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
...

../Entity/Brand.php

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="brands")
 */
class Brand
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="status", type="string", length=1)
     */
    private $status = 'a';

    /**
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
...

每个产品,品牌和部门都有自己的网址,该网址由object_typeobject_id设置的路由表中保存,其中object_type只是department,{ {1}}或productbrand是相应产品,品牌或部门的唯一ID。

object_id

../Entity/Routing.php

我真正感到困难的是如何设置关系,因此部门,产品和品牌可以从单个路由实体访问其URL。

我尝试将关系添加到use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="routing") */ class Routing { /** * @ORM\Id * @ORM\Column(name="id", type="integer", length=11) * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\Column(name="object_id", type="integer", length=11) */ private $objectId; /** * @ORM\Column(name="object_type", type="string", length=100) */ private $objectType; /** * @ORM\Column(name="url", type="text") */ private $url; ... ,但似乎不喜欢这样。是否可以这样设置?

我基本上想要实现的是获取数据对象并能够获取对象的URL,例如:

$objectId

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:4)

经过进一步的研究,我发现一个人(Dirk Olbertz)知道谁有同样的问题。

可在以下网址找到相关信息:Google Groups: Multiple JoinColumns?

我现在已经实现了这一点,我将解释我是如何做到这一点的,这可能对其他人有帮助。

我的问题的答案是使用单表继承。

我需要做的第一件事是更新routing实体以使用单表继承:

../Entity/Routing.php

/**
 * @ORM\Entity
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="object_type", type="string")
 * @ORM\DiscriminatorMap({"product" = "ProductRouting", "department" = "DepartmentRouting", "brand" = "BrandRouting"})
 * @ORM\Table(name="routing")
 */
class Routing
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", length=11)
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
...

DiscriminatorColumn允许我指定用于链接的列,在本例中为object_type字段。

DiscriminatorMap允许我指定object_type将与哪些实体相关联。

然后必须创建这些实体以扩展Routing实体。

../Entity/ProductRouting.php

/**
 * @ORM\Entity
 */
class ProductRouting extends Routing
{
    /**
     * @ORM\ManyToOne(targetEntity="Product")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id")
     */
    protected $product;
...

../Entity/DepartmentRouting.php

/**
 * @ORM\Entity
 */
class DepartmentRouting extends Routing
{
    /**
     * @ORM\ManyToOne(targetEntity="Department")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id")
     */
    protected $department;
...

../Entity/BrandRouting.php

/**
 * @ORM\Entity
 */
class BrandRouting extends Routing
{
    /**
     * @ORM\ManyToOne(targetEntity="Brand")
     * @ORM\JoinColumn(name="object_id", referencedColumnName="id")
     */
    protected $brand;
...

然后,在每个ProductDepartmentBrand个实体中,我需要添加新的$routings

../Entity/Product.php

...
class Product
{
    ...
    /**
     * @ORM\OneToMany(targetEntity="ProductRouting", mappedBy="product", cascade={"all"})
     */
    private $routings;
...

../Entity/Department.php

...
class Department
{
    ...
    /**
     * @ORM\OneToMany(targetEntity="DepartmentRouting", mappedBy="department", cascade={"all"})
     */
    private $routings;
...

../Entity/Brand.php

...
class Brand
{
    ...
    /**
     * @ORM\OneToMany(targetEntity="BrandRouting", mappedBy="brand", cascade={"all"})
     */
    private $routings;
...

希望有帮助...