【问题标题】:Doctrine one-to-one unidirectional学说一对一单向
【发布时间】:2017-04-27 10:20:41
【问题描述】:

在带有 Doctrine 的 Symfony 3 中,我试图获得一个一对一的单向关系,两个表共享相同的主键工作。为此,我试图在Doctrine Association Mapping 页面上复制该示例。

但是,一对一的 uni 文档没有 setter 和 getter 的示例 - 也没有目标实体上 id 字段的定义。所以我试着在自己周围做实验。

这些是我的实体:

class Country
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="MySubEntity", cascade={"persist", "remove"})
     * @ORM\JoinColumn(name="id", referencedColumnName="id", nullable=true)
     */
    private $mysubentity;
    [...]
    /**
     * @return MySubEntity
     */
    public function getMySubEntity()
    {
        return $this->mysubentity;
    }

    /**
     * @param MySubEntity $mysubentity
     */
    public function setMySubEntity($mysubentity)
    {
        $this->mysubentity = $mysubentity;
    }
}

class MySubEntity
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    [..]

    /**
     * Set id
     *
     * @param $id
     *
     * @return MySubEntity
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

当我坚持国家实体时,我收到Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails。检查数据时,我可以看到 Doctrine 试图将 MySubEntity 的 id 设置为 0。

有人知道我需要做什么才能从 Country 实体自动填充 MySubEntity $id 字段吗?

【问题讨论】:

  • 首先,我认为 nullable= true 不适合 id 字段
  • 你有两个 name=id 的字段
  • nullable=false 用于两个 $id 字段。 nullable=true 用于关系,因为可以是关联的行,但不必(可选)。两个$id 字段中的每一个都位于各自的实体中,所以应该没问题。

标签: php symfony doctrine-orm orm


【解决方案1】:

您需要将 JoinColumn 名称属性更改为除 id 以外的任何其他内容:

/**
 * @ORM\OneToOne(targetEntity="MySubEntity", cascade={"persist", "remove"})
 * @ORM\JoinColumn(name="mysubentity_id", referencedColumnName="id", nullable=true)
 */
private $mysubentity;

这是做什么的: JoinColumn 告诉学说关系保存在哪个数据库列中。因此,如果您将其称为 mysub_id,您的主实体将有一个具有该名称的列,其中将保留 referencedColumn 值(您的子实体的 ID)。

如果您说 JoinColumn 名称是 id 已被您的实体的主键使用,则您有冲突。

编辑:

我错过了共享相同主键的观点。这有什么具体原因吗? 但是,如果您真的需要出于遗留原因这样做,请查看

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

或通过更改生成策略(本例中为 NONE 或自定义)自行生成 subEntity 的主键值的可能性

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#identifier-generation-strategies

【讨论】:

  • 你是完全正确的,我在两个表中使用相同的主键并没有真正的原因 - 即使这是有效的并且在我看来应该适用于 Doctrine。我更改了架构,而是添加了一个新的my_sub_entity_id 列。然后我更改了注释以反映新的键名,它立即起作用。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多