RektByAyyLMAO RektByAyyLMAO - 7 months ago 35
PHP Question

doctrine:schema:update not creating OneToOne relations

When I run the following command:

php app/console doctrine:schema:update --force --dump-sql


It returns this message:
Nothing to update - your database is already in sync with the current entity metadata
.

I have two Entities, User and UserProfile.

User.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;
...


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="user_id", type="integer")
* @ORM\OneToOne(targetEntity="User", mappedBy="id")
*/
private $userId;
...


I've already tried clearing the cache.

UPDATE #1

User.php

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


UserProfile.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;

Answer

You have a couple of options here, if you want a bi-direction association, meaning you want to be able to access the other entity from either of them then you will want to use another property( NOT the $id) to accomplish this. Something like:

/**
 * @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;

    ...
}

Then in 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;

    ...
}

This will allow you to do $userProfile->getUser() and also $user->getProfile().

If you want to use the userId as your primary key for the UserProfile table, you can it just involves more work to set that up and you have to explicitly set it in your application. Easier just to reference it on another field.

Unidirectional

User.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;

    ...
}

UserProfile.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;

    ...
}

This will only allow you to do $userProfile->getUser(). Likely not what you are looking for. The other unidirectional solution is from the user object towards the UserProfile, like this:

/**
 * @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;

    ...
}

Then in 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;

    ...
}

This way you can do $user->getProfile().