【问题标题】:doctrine:schema:update not creating OneToOne relations学说:架构:更新不创建 OneToOne 关系
【发布时间】:2016-09-04 15:39:36
【问题描述】:

当我运行以下命令时:php app/console doctrine:schema:update --force --dump-sql

它返回这条消息:Nothing to update - your database is already in sync with the current entity metadata

我有两个实体,用户和用户配置文件。

用户.php

/**
 * @ORM\Table(name="users", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User implements UserInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\OneToOne(targetEntity="UserProfile", inversedBy="user_id")
     */
    private $id;
...

用户配置文件.php

/**
 * @ORM\Table(name="users_profiles", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserProfileRepository")
 */
class UserProfile
{
    /**
     * @ORM\Id
     * @ORM\Column(name="user_id", type="integer")
     * @ORM\OneToOne(targetEntity="User", mappedBy="id")
     */
    private $userId;
...

我已经尝试清除缓存了。

更新 #1

用户.php

/**
 * @ORM\Id
 * @ORM\Column(name="id", type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 * @ORM\OneToOne(targetEntity="UserProfile", mappedBy="userId")
 */
private $id;

用户配置文件.php

/**
 * @ORM\Id
 * @ORM\Column(name="user_id", type="integer")
 * @ORM\OneToOne(targetEntity="User", inversedBy="id")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 */
private $userId;

【问题讨论】:

    标签: php symfony orm doctrine-orm one-to-one


    【解决方案1】:

    您在这里有几个选项,如果您想要双向关联,这意味着您希望能够从其中任何一个访问另一个实体,那么您将需要使用另一个属性(不是 $id)来实现这一点。比如:

    /**
     * @ORM\Table(name="users", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
     * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
     */
    class User implements UserInterface
    {
        /**
         * @ORM\Id
         * @ORM\Column(name="id", type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")         
         */
        private $id;
    
        /**
         * @ORM\OneToOne(targetEntity="UserProfile", mappedBy="userId")
         */
        private $profile;
    
        ...
    }
    

    然后在 UserProfile.php 中

    /**
     * @ORM\Table(name="users_profiles", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
     * @ORM\Entity(repositoryClass="AppBundle\Repository\UserProfileRepository")
     */
    class UserProfile
    {
        /**
         * @ORM\Id
         * @ORM\Column(name="id", type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")         
         */
        private $id;
    
        /**
         * @ORM\OneToOne(targetEntity="User", inversedBy="profile")
         * @ORM\JoinColumn(name="userId", referencedColumnName="id")
         */
        private $user;
    
        ...
    }
    

    这将允许您执行$userProfile->getUser()$user->getProfile()

    如果您想使用 userId 作为 UserProfile 表的主键,您只需要做更多的工作来设置它,并且您必须在应用程序中显式设置它。更容易在另一个字段中引用它。

    单向

    用户.php

    /**
     * @ORM\Table(name="users", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
     * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
     */
    class User implements UserInterface
    {
        /**
         * @ORM\Id
         * @ORM\Column(name="id", type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")         
         */
        private $id;
    
        ...
    }
    

    用户配置文件.php

    /**
     * @ORM\Table(name="users_profiles", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
     * @ORM\Entity(repositoryClass="AppBundle\Repository\UserProfileRepository")
     */
    class UserProfile
    {
    
        /**
         * @ORM\OneToOne(targetEntity="User", inversedBy="profile")
         * @ORM\JoinColumn(name="userId", referencedColumnName="id")
         */
        private $user;
    
        ...
    }
    

    这只会让你做$userProfile->getUser()。可能不是您要查找的内容。另一种单向解决方案是从用户对象到 UserProfile,如下所示:

    /**
     * @ORM\Table(name="users", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
     * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
     */
    class User implements UserInterface
    {
        /**
         * @ORM\Id
         * @ORM\Column(name="id", type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")         
         */
        private $id;
    
        /**
         * @ORM\OneToOne(targetEntity="UserProfile", mappedBy="id")
         */
        private $profile;
    
        ...
    }
    

    然后在 UserProfile.php 中

    /**
     * @ORM\Table(name="users_profiles", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})
     * @ORM\Entity(repositoryClass="AppBundle\Repository\UserProfileRepository")
     */
    class UserProfile
    {
        /**
         * @ORM\Id
         * @ORM\Column(name="id", type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")         
         */
        private $id;
    
        ...
    }
    

    这样你就可以做到$user->getProfile()

    【讨论】:

    • 虽然我理解为什么它是必要和推荐的,但我需要 2 个额外的属性和 1 个额外的字段让我感到困扰。两个表中的行将完全相同,并且 user_profile_id 将与 user_id 相同(除非出现严重错误)。不管怎样,你的回答解决了我的问题,谢谢!
    • 你可以只用一列就可以了,它只是很多额外的工作,对我来说只是更容易添加额外的属性。但我确实感受到了你的沮丧。很高兴这个答案很有帮助。
    • 在最后一个选项中,在$profile 属性上,您写了mappedBy="userId",但任何地方都没有userId
    • 复制粘贴失败,应该是id我已经更新答案了
    • $profile 也需要@ORM\JoinColumn(name="profile_id", referencedColumnName="id"),对吧?
    【解决方案2】:

    inversedBy 指的是属性,而不是数据库字段。

    inversedBy="user_id" 更改为inversedBy="userId"

    您还应该根据文档使用 JoinColumn,而不是 Column 和 referencedColumnName:

    http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-one-unidirectional

    【讨论】:

    • 它似乎仍然不起作用。我已经在 OP 中更新了你的提示代码。
    猜你喜欢
    • 1970-01-01
    • 2012-09-21
    • 2014-07-31
    • 2017-10-19
    • 2020-10-18
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多