Php 通过外国实体在同花顺上的例外实现同一身份的原则

Php 通过外国实体在同花顺上的例外实现同一身份的原则,php,symfony,doctrine-orm,doctrine,Php,Symfony,Doctrine Orm,Doctrine,我有User和UserProfileOneToOne-相关实体。它们应该始终成对存在,没有UserProfile就不应该有User 用户应该从autoincrement获取其id,而UserProfile应该具有用户id。因此,它们都应该具有相同的id,并且没有其他列来设置关系() UserProfile的id同时是主键(PK)和外键(FK) 我设法设置了它,但它要求先保存用户,然后在单独的步骤中创建并保存UserProfile 我想要的是,UserProfile总是在构造函数中使用User创建

我有
User
UserProfile
OneToOne-相关实体。它们应该始终成对存在,没有
UserProfile
就不应该有
User

用户应该从autoincrement获取其id,而UserProfile应该具有用户id。因此,它们都应该具有相同的id,并且没有其他列来设置关系()

UserProfile的id同时是主键(PK)和外键(FK)

我设法设置了它,但它要求先保存用户,然后在单独的步骤中创建并保存UserProfile

我想要的是,UserProfile总是在构造函数中使用User创建的,但是如果我这样做,我会得到以下异常:

条令\ORM\ORMInvalidArgumentException:类型为'AppBundle\entity\UserProfile'(AppBundle\entity)的给定实体\UserProfile@0000000052e1b1eb00000000409c6f2c)未设置标识/标识值。无法将其添加到身份映射。

请参阅下面的代码–它可以工作,但不是我想要的方式。php注释显示了我想要实现的目标

Test.php

/**
 * It works, both saving and loading.
 * BUT, it requires that I create and save UserProfile 
 * in a separate step than saving User step.
 */

// create and save User
$user = new User();
$objectManager->persist($user);
$objectManager->flush();

// create and save UserProfile (this should be unnecessary)
$user->createProfile()
$objectManager->flush();
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @var int
     *
     * @ORM\Column(name="uid", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * It's NULL at first, I create it later (after saving User).
     * 
     * @var UserProfile|null
     *
     * @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade="persist")
     */
    private $profile = null;

    public function __construct()
    {
        // I want to create UserProfile inside User's constructor,
        // so that it is always present (never NULL):
        //$this->profile = new UserProfile($this);

        // but this would give me error:
        //
        // Doctrine\ORM\ORMInvalidArgumentException: 
        // The given entity of type 'AppBundle\Entity\UserProfile' 
        // (AppBundle\Entity\UserProfile@0000000058af220a0000000079dc875a)
        // has no identity/no id values set. It cannot be added to the identity map.
    }

    public function createProfile()
    {
        $this->profile = new UserProfile($this);
    }   
}
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="profiles")
 */
class UserProfile
{
    /**
     * – UserProfile's "uid" column points to User's "uid" column
     * – it is PK (primary key)
     * - it is FK (foreign key) as well
     * – "owning side"
     *
     * @var User
     *
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="User", inversedBy="profile")
     * @ORM\JoinColumn(name="uid", referencedColumnName="uid", nullable=false)
    */
    private $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }    
}
User.php

/**
 * It works, both saving and loading.
 * BUT, it requires that I create and save UserProfile 
 * in a separate step than saving User step.
 */

// create and save User
$user = new User();
$objectManager->persist($user);
$objectManager->flush();

// create and save UserProfile (this should be unnecessary)
$user->createProfile()
$objectManager->flush();
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @var int
     *
     * @ORM\Column(name="uid", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * It's NULL at first, I create it later (after saving User).
     * 
     * @var UserProfile|null
     *
     * @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade="persist")
     */
    private $profile = null;

    public function __construct()
    {
        // I want to create UserProfile inside User's constructor,
        // so that it is always present (never NULL):
        //$this->profile = new UserProfile($this);

        // but this would give me error:
        //
        // Doctrine\ORM\ORMInvalidArgumentException: 
        // The given entity of type 'AppBundle\Entity\UserProfile' 
        // (AppBundle\Entity\UserProfile@0000000058af220a0000000079dc875a)
        // has no identity/no id values set. It cannot be added to the identity map.
    }

    public function createProfile()
    {
        $this->profile = new UserProfile($this);
    }   
}
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="profiles")
 */
class UserProfile
{
    /**
     * – UserProfile's "uid" column points to User's "uid" column
     * – it is PK (primary key)
     * - it is FK (foreign key) as well
     * – "owning side"
     *
     * @var User
     *
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="User", inversedBy="profile")
     * @ORM\JoinColumn(name="uid", referencedColumnName="uid", nullable=false)
    */
    private $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }    
}
UserProfile.php

/**
 * It works, both saving and loading.
 * BUT, it requires that I create and save UserProfile 
 * in a separate step than saving User step.
 */

// create and save User
$user = new User();
$objectManager->persist($user);
$objectManager->flush();

// create and save UserProfile (this should be unnecessary)
$user->createProfile()
$objectManager->flush();
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\UserRepository")
 * @ORM\Table(name="users")
 */
class User
{
    /**
     * @var int
     *
     * @ORM\Column(name="uid", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * It's NULL at first, I create it later (after saving User).
     * 
     * @var UserProfile|null
     *
     * @ORM\OneToOne(targetEntity="UserProfile", mappedBy="user", cascade="persist")
     */
    private $profile = null;

    public function __construct()
    {
        // I want to create UserProfile inside User's constructor,
        // so that it is always present (never NULL):
        //$this->profile = new UserProfile($this);

        // but this would give me error:
        //
        // Doctrine\ORM\ORMInvalidArgumentException: 
        // The given entity of type 'AppBundle\Entity\UserProfile' 
        // (AppBundle\Entity\UserProfile@0000000058af220a0000000079dc875a)
        // has no identity/no id values set. It cannot be added to the identity map.
    }

    public function createProfile()
    {
        $this->profile = new UserProfile($this);
    }   
}
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="profiles")
 */
class UserProfile
{
    /**
     * – UserProfile's "uid" column points to User's "uid" column
     * – it is PK (primary key)
     * - it is FK (foreign key) as well
     * – "owning side"
     *
     * @var User
     *
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="User", inversedBy="profile")
     * @ORM\JoinColumn(name="uid", referencedColumnName="uid", nullable=false)
    */
    private $user;

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

测试应用程序:

请记住,实际对象需要由EntityManager保存。 仅仅将该类作为对另一个类的引用并不会使entityManager意识到这两个类都存在的事实

您应该将实际的userProfile持久化到EntityManager,以便能够保存关系

因负面评论而更新:

请阅读条令文件。。。你应该坚持

以下示例是本章用户评论示例的扩展。假设在我们的应用程序中,每当用户写第一条评论时,就会创建一个用户。在这种情况下,我们将使用以下代码:

<?php
$user = new User();
$myFirstComment = new Comment();
$user->addComment($myFirstComment);

$em->persist($user);
$em->persist($myFirstComment);
$em->flush();

您应该考虑创建包含EntyMealMead的UService服务,并负责创建、链接和持久化用户+用户配置文件实体。

ID是数据库的事情,而不应该是模型中的一个问题。不要认为它们需要相同的主键值。或者如果做不到这一点,就放弃一个需要自动,另一个不需要的概念。@Cerad我正在一个遗留应用程序上构建——数据库就是它。我需要将原则调整到当前模式,而不是相反…另外,上面的代码可以工作。条令可以处理作为主键的外键。它只是不能在一次刷新中持久化实体。或者至少我在寻找答案,如何配置条令,这样就可以了。足够公平了。如果你做一个搜索,那么你会发现这个问题的几百种变体。所有答案都相同。请参阅,您似乎需要更改关系的拥有方。不,由于
cascade=“persist”
,配置文件已匹配以保持。如果我删除它并“手动”保留配置文件,问题仍然存在。这没有帮助,我已经尝试过了(现在,为了完全确定,我甚至再试一次)。同样的错误。
/app/console-cache:clear&&sudo/etc/init.d/nginx-restart&&sudo/etc/init.d/php5-fpm-restart&&sudo/etc/init.d/memcached-restart&/app/console-cache:clear
你能分享一下你是如何尝试单独持久化的吗?见报告:测试在这里: