原则 2:如何更新一对一的双向

Posted

技术标签:

【中文标题】原则 2:如何更新一对一的双向【英文标题】:Doctrine 2: How to update one-to-one bidirectional 【发布时间】:2015-08-03 10:08:27 【问题描述】:

我在更新一对一双向关联时遇到问题。

用户实体

/**
 *
 * @ORM\Table(name="test_user")
 */
class User

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="login", type="string", length=32, nullable=false, unique=true)
     */
    private $login;


    /**
     *
     * @ORM\OneToOne(targetEntity="Points", mappedBy="user", cascade="persist")
     */
    private $points;

     ...


    /**
     * Set points
     */
     public function setPoints(array $points)
     
        $this->points = new Points($points);
        $this->points->setUser($this);

        return $this;
     

    /**
     * Get points
     */
    public function getPoints()
    
        return $this->points;
    


积分实体

/**
 * Points
 *
 * @ORM\Table(name="test_user_points")
 * @ORM\Entity
 */
class Points 

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var integer
     *
     * @ORM\Column(type="integer",  nullable=false)
     */
    private $points;


    /**
     * @var string
     *
     * @ORM\Column(name="period", type="string", length=24)
     */
     private $period;


    /**
     * @var User
     *
     * @ORM\OneToOne(targetEntity="User", inversedBy="points")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id",onDelete="CASCADE", nullable=false)
     */
    private $user;





    /**
     * Constructor
     */
    public function __construct(array $params = array())
    
        $hydrator = new MyHydrator();
        $hydrator->hydrate($params, $this);
    


    ...

    /**
     * Set user
     *
     * @param User $user
     */
    public function setUser(User $user = null)
    
        $this->user = $user;

        return $this;
    

    /**
     * Get user
     *
     * @return User
     */
    public function getUser()
    
        return $this->user;
    



MyHydrator 正在从数组(第一个参数)转换为对象(第二个参数)。这很重要,我必须使用它。

我的保存功能如下所示:

public function save(array $data)

    ...

    // This is how my input data looks

    $data = array(
        'login' => 'Test',
        array(
            'points' => 999,
            'period' => 'monthly'
        )
    );

    if ($userExists) 
        // UPDATE
        $hydrator = new MyHydrator();
        $hydrator->hydrate($data, $userExists);
        $this->em->persist($userExists);
        $this->em->flush();

     else 
        // INSERT
        $user = new User($data);
        $this->em->persist($user);
        $this->em->flush();
    

插入数据库完美无缺,但是当我尝试更新记录时出现错误:

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4' for key 'UNIQ_DAD93D6EA76ED395'

4points表中user_id列的值

如何编辑现有记录而不会出现关于重复 ID 的错误?

【问题讨论】:

【参考方案1】:

它很旧,但由于我遇到了类似的问题,我以这种方式解决了它: 在用户中

public function setPoints($points)

    if ($this->points !== null) 
        $this->points->setUser(null);
    
    $this->points = $points;
    $points->setUser($this);

【讨论】:

以上是关于原则 2:如何更新一对一的双向的主要内容,如果未能解决你的问题,请参考以下文章

三大框架 之 Hibernate查询(一对多多对多查询关系)

如何在外键上进行双向一对一关联[重复]

如何在 Hibernate 3.6 中正确级联保存主键上的一对一双向关系

Fluent NHibernate:如何创建一对多的双向映射?

java之hibernate之基于外键的双向一对一关联映射

hibernate 之 关联映射的基于外键的双向一对一关联