首页 > 解决方案 > 学说:同一个属性可以与两个不同的目标属性建立关系吗?

问题描述

这种 OneToOne 关系是否可能与 Doctrine(在 Symfony 中)?

User                     Time
+----------+             +-------+
| ...      |             | ...   |
| time_id  |o-----+-----o| user  |
|          |      |      | ...   |
| time2_id |o-----+      | type  |
| ...      |             +-------+
+----------+

也就是说,一个用户可能有两个与之关联的不同时间实体:一个是 type=0,另一个是 type=1。

我本可以将 Time 拆分为两个不同的实体,但我认为这样我可以省去复制一些代码,因为 Time 实体有一个 eventListener 和更多相关的代码......

我已经这样编码了:

class Time
{
...
    /**
     * @ORM\OneToOne(targetEntity=User::class, mappedBy="time, cascade={"persist"})
     * @ORM\OneToOne(targetEntity=User::class, mappedBy="time2", cascade={"persist"})
     */
    private $user;
...}

class User
{
...
    /**
     * @ORM\OneToOne(targetEntity=Time::class, inversedBy="user", cascade={"persist"})
     * @ORM\JoinColumn(name="time_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time;

    /**
     * @ORM\OneToOne(targetEntity=Time::class, inversedBy="user", cascade={"persist"})
     * @ORM\JoinColumn(name="time2_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time2;
...}

事实上,我完美地使用它,但 Symfony 默默地抱怨(在Symfony 工具栏/Doctrine/Entities Mapping > Mapping errors 中):

    App\Entity\User     

    The mappings App\Entity\User#time2 and App\Entity\Time#user are inconsistent with each other.

显然,Doctrine 不喜欢$user上的第二个@ORM\OneToOne,并且正在丢弃它。

这段代码会导致哪些假设性的不当行为?

注意:学说/通用 v2.11

标签: phpdoctrine-ormdoctrineone-to-one

解决方案


FWIW,只要放弃逆关系部分,就可以建立这种关系:

User                     Time
+----------+             +-------+
| ...      |             | ...   |
| time_id  |o-----+-----o|       |
|          |      |      |       |
| time2_id |o-----+      | type  |
| ...      |             +-------+
+----------+

实施者:

class Time
{
...
}

class User
{
...
    /**
     * @ORM\OneToOne(targetEntity=Time::class, cascade={"persist"})
     * @ORM\JoinColumn(name="time_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time;

    /**
     * @ORM\OneToOne(targetEntity=Time::class, cascade={"persist"})
     * @ORM\JoinColumn(name="time2_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $time2;
...}

请查看此链接以了解Owning vs Inverse 关系

就我而言,这完全符合我的需求,因为相反的部分适用于以下方法:

$Time->getUser();

我可以预测。


推荐阅读