symfony 按不是主键- id的referencedColumnName联接列

ars1skjm  于 2023-10-23  发布在  其他
关注(0)|答案(2)|浏览(142)

我是新手在Symfony教义和需要一些帮助加入实体。
通常列是通过主键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字段连接一对一关系中的两列

/**
     * 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或我试图做的是不可能的?
谢谢你们

hmmo2u0o

hmmo2u0o1#

你把应该在@JoinColumn声明中引用的列名和字段名弄混了。

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

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

用户详细信息

/**
 * @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表中的join-columm如下所示:

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

6jygbczu2#

引用Doctrine文档:
不可能使用指向非主键的连接列。Doctrine会认为这些是主键,并使用数据创建延迟加载代理,这可能导致意外的结果。出于性能原因,Doctrine可以在运行时不验证此设置的正确性,而只能通过XMLSchema命令验证。
我遇到了同样的问题,我通过只Map到主键字段来解决它。如果我需要通过其他字段获取相关实体,我在实体存储库中实现方法。

相关问题