【问题标题】:Join columns by referencedColumnName that is not primary key - id通过非主键的 referencedColumnName 连接列 - id
【发布时间】:2016-11-05 11:02:28
【问题描述】:

我是 Symfony Doctrine 的新手,在加入实体方面需要一些帮助。

通常列是按主键 ID 连接

    /**
     * User
     *
     * @ORM\Table(name="users")
     * @ORM\Entity(repositoryClass="MainBundle\Repository\UserRepository")
     * UniqueEntity("email", message="Account with email already exists.")
     */
    class User implements AdvancedUserInterface, \Serializable
    {
    /**
         * @var \MainBundle\Entity\PersonDetails
         *
         * @ORM\ManyToOne(targetEntity="MainBundle\Entity\Person")
         * @ORM\JoinColumns({
         *  @ORM\JoinColumn(name="person_details_id", referencedColumnName="id", nullable=true)
         * })
         */
    private $personDetails = null;

没关系。

但问题是我想通过用户实体中的 id 字段加入 Relation OneToOne 中的两列


    /**
     * User
     *
     * @ORM\Table(name="users")
     * @ORM\Entity(repositoryClass="MainBundle\Repository\UserRepository")
     * UniqueEntity("email", message="Account with email already exists.")
     */
    class User implements AdvancedUserInterface, \Serializable
    {
    /**
         * @var \MainBundle\Entity\PersonDetails
         *
         * @ORM\ManyToOne(targetEntity="MainBundle\Entity\Person")
         * @ORM\JoinColumn(name="id", referencedColumnName="user_id", nullable=true)
             * })
             */
        private $personDetails = null;

当我尝试以这种方式加入列时出现错误

MainBundle\Entity\PersonDetails 上的主键 ID 缺失值

是否可以索引 id 以外的其他字段,或者我试图做的事情是不可能的?

谢谢大家。

【问题讨论】:

  • 请用正确的缩进修正问题中的代码,它很难阅读。 User 实体中的 id fieldprimary id 有什么区别?似乎缺少属性(即带有@ORM\Id() 的属性)......回答您的问题需要这些属性。

标签: symfony doctrine-orm


【解决方案1】:

您混淆了@JoinColumn 声明中应引用的列名和字段名。

@JoinColumn(name="id", referencedColumnName="user_id")

这样,Doctrine 在您的 User 实体上查找名为 user_id 的字段/属性。我猜你希望连接表中的列被命名为 user_id 并且条目是 idUser 实体。

用户详情

/**
 * @ORM\Entity
 */
class UserDetail
{
    /**
     * @ORM\ManyToOne(
     *   targetEntity="User",
     *   inversedBy="details"
     * )
     * @ORM\JoinColumn(
     *   name="user_id",
     *   referencedColumnName="id"
     * )
     */
    protected $user;

    public function setUser(User $user)
    { 
        $this->user = $user;

        return $this;
    }

    /** @ORM\Column() */
    protected $key;

    /** @ORM\Column() */
    protected $value;

    public function __construct($key, $value)
    {
       $this->key = $key;
       $this->value = $value;
    }

用户

class User
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     */
    protected $id;

    /** 
     * @ORM\OneToMany(
     *   targetEntity="UserDetail",
     *   mappedBy="user", 
     *   cascade={
     *     "persist",
     *     "remove",
     *     "merge"
     *   },
     *   orphanRemoval=true
     * )
     */
    protected $details;

    public function __construct()
    {
        $this->details = new ArrayCollection();
    }

    public function addDetail(UserDetail $detail)
    {
        $detail->setUser($this);
        $this->details->add($detail);

        return $this;
    }

现在,如果您像这样向您的 User 添加详细信息并在之后保留/刷新:

$user->addDetail(new UserDetail('Height', '173cm'));

这将导致user_detail 表中的连接列如下所示:

| key           | value     | user_id |
|---------------|-----------|---------|
| Height        | 173cm     | 1       |

【讨论】:

    【解决方案2】:

    引用Doctrine documentation

    不能使用指向非主键的连接列。 Doctrine 会认为这些是主键并创建延迟加载 代理与数据,这可能会导致意想不到的结果。教义 可以出于性能原因不验证这个的正确性 在运行时设置,但只能通过 Validate Schema 命令。

    我遇到了同样的问题,我通过仅对作为主键的字段执行映射来解决它。如果需要通过其他字段获取相关实体,我实现了Entity repository中的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-22
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 2014-12-30
      相关资源
      最近更新 更多