在Doctrine 2继承中覆盖inversedBy映射 [英] Overriding inversedBy mapping in Doctrine 2 inheritance

查看:101
本文介绍了在Doctrine 2继承中覆盖inversedBy映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体:

class Restaurant
{
    /**
     * @OneToMany(targetEntity="CollectionTime", mappedBy="restaurant")
     */
    protected $collectionTimes;

    /**
     * @OneToMany(targetEntity="DeliveryTime", mappedBy="restaurant")
     */
    protected $deliveryTimes;
}

映射到同一个实体的两个子类:

Mapping to two subclasses of the same entity:

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorMap({
 *   "CollectionTime" = "CollectionTime",
 *   "DeliveryTime"   = "DeliveryTime"
 * })
 */
abstract class OrderTime
{
    /**
     * @ManyToOne(targetEntity="Restaurant")
     */
    protected $restaurant;
}

/**
 * @Entity
 */
class CollectionTime extends OrderTime
{
}

/**
 * @Entity
 */
class DeliveryTime extends OrderTime
{
}

现在问题是, doctrine orm:validate-schema 报告以下错误:

Now the problem is, doctrine orm:validate-schema reports the following errors:



  • 字段Restaurant#collectionTimes是双向关系的反面,但指定的mappedBy目标实体CollectionTime#餐厅上的关联不包含所需的inversedBy = collectionTimes属性。

  • The field Restaurant#collectionTimes is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity CollectionTime#restaurant does not contain the required 'inversedBy=collectionTimes' attribute.

字段Restaurant#deliveryTimes位于双向关系,但目标实体DeliveryTime#餐厅上指定的mappedBy关联不包含所需的inversedBy = deliveryTimes属性。

The field Restaurant#deliveryTimes is on the inverse side of a bi-directional relationship, but the specified mappedBy association on the target-entity DeliveryTime#restaurant does not contain the required 'inversedBy=deliveryTimes' attribute.

简而言之,Doctrine期望每个 mappedBy 在另一边有一个 inversedBy

In short, Doctrine expects every mappedBy to have an inversedBy on the other side.

唯一的解决方案到目前为止,请将 OrderTime :: $ restaurant 属性和映射到 CollectionTime DeliveryTime ,只是为了能够添加正确的 inversedBy 映射:

The only solution I can see so far is to move the OrderTime::$restaurant property and mapping to CollectionTime and DeliveryTime, just to be able to add the proper inversedBy mapping:

abstract class OrderTime
{
}

/**
 * @Entity
 */
class CollectionTime extends OrderTime
{
    /**
     * @ManyToOne(targetEntity="Restaurant", inversedBy="collectionTimes")
     */
    protected $restaurant;
}

/**
 * @Entity
 */
class DeliveryTime extends OrderTime
{
    /**
     * @ManyToOne(targetEntity="Restaurant", inversedBy="deliveryTimes")
     */
    protected $restaurant;
}

但这很麻烦,违反了继承原则。

But it is cumbersome and goes against the principle of inheritance.

是否有一种方法可以覆盖子类中的 inversedBy 属性,而无需(重新)声明整个属性在子类?

Is there a way to just override the inversedBy attribute in the subclasses, without having to (re)declare the whole property in the subclass?

我已经研究了 @ AssociationOverrides @ AttributeOverrides ,但它们似乎没有为此设计。

I've looked into @AssociationOverrides and @AttributeOverrides, but they don't seem to be designed for this purpose.

推荐答案

单向/双向



Doctrine 2使用单向关联和双向关联。

定义单向关联时,必须省略 inversedBy 参数,因为关联不被反转。

When defining a unidirectional association you have to omit the inversedBy parameter, because the association isn't inversed.

定义双向关联时,必须使用 c $ c>参数 c> >(这是实际包含Doctrine的所有元数据以正确映射关联的一面),您必须使用 > 参数在反转方面(以便Doctrine知道在哪里查找关联的实际映射元数据。)

When defining a bidirectional association you have to use the inversedBy parameter on the owning side (that's the side that actually contains all metadata for Doctrine to properly map the association), and you have to use the mappedBy parameter on the inversed side (so that Doctrine knows where to look for the actual mapping metadata for the association).

所以您既可以使用 inversedBy mappedBy (双向)或您

So you either use both inversedBy and mappedBy (bidirectional) or you don't use them at all (unidirectional).


但是这是麻烦的,违背了继承的原则。

But it is cumbersome and goes against the principle of inheritance.

我认为这取决于你看看它:

I think that depends on how you look at it:

如果你只看代码(而不是映射),你是正确的。 OrderTime 的具体实现共享一个属性 $ restaurant (可能是getter,setter和其他逻辑),所以该原则规定您在 OrderTime 中定义。

If you only look at the code (not the mapping), you are correct. Both concrete implementations of OrderTime share a property $restaurant (and probably getters, setters, and maybe other logic), so the principle dictates that you define that in OrderTime.

但是,当您查看映射时,您有2个不同的关联:将 Restaurant :: $ collectionTimes CollectionTime :: $ restaurant ,而一个连接 Restaurant :: $ deliveryTimes DeliveryTime :: $ restaurant 在一起。

But when you look at the mapping, you have 2 different associations: One that ties Restaurant::$collectionTimes and CollectionTime::$restaurant together, and one that ties Restaurant::$deliveryTimes and DeliveryTime::$restaurant together.

因为这是两个不同的关联,所以Doctrine希望你们正确定义它们是公平的。

Because these are 2 different associations, it's only fair that Doctrine wants you to properly define them both.

你仍然可以坚持原则的继承方式:在 OrderTime 中定义所需的所有共享逻辑,即使是属性 $ restaurant ,只是不添加映射元数据。在具体实现中,您可以使用适当的映射元数据重新声明属性 $ restaurant

You can still stick to principle of inheritance in the following way: Define all shared logic you need in OrderTime, even the property $restaurant, just don't add the mapping metadata. In the concrete implementations you can redeclare the property $restaurant with the proper mapping metadata.

唯一的原因要重新声明这些混合物中的属性 $ restaurant ,那么您正在使用注释来映射元数据。当使用Yaml或XML时,您不必重新声明属性,因为映射元数据将在不同的文件中。

The only reason you have to redeclare the property $restaurant in those concretes is that you're using Annotations for mapping metadata. When using Yaml or XML, you don't have to redeclare the property because the mapping metadata will be in separate files.

所以其实它不是代码/逻辑,在这些具体实现中重新定义,它是映射元数据。

So in fact it's not code/logic you're defining in those concrete implementations, it's the mapping metadata.

那些 OrderTime 类似于价值对象给我(而不是实体):一个小的简单对象,如金钱或日期范围,其平等不基于身份。

Those OrderTime classes look more like Value Objects to me (not Entities): A small simple object, like money or a date range, whose equality isn't based on identity.

Doctrine将支持从2.5版开始的Value对象(参见此处)。

Doctrine will support Value Objects starting with version 2.5 (see here).

这篇关于在Doctrine 2继承中覆盖inversedBy映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆