doctrine2 OneToMany关系将NULL作为外键插入 [英] doctrine2 OneToMany relationship inserts NULL as the foreign key

查看:89
本文介绍了doctrine2 OneToMany关系将NULL作为外键插入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个双向的OneToMany关系,使用Doctrine 2作为ZendFramework 1.11.2中的ORM。

I have a bi-directional OneToMany relationship using Doctrine 2 as an ORM within the ZendFramework 1.11.2.

注意:Doctrine没有创建数据库表。数据库是MySQL。

Note: Doctrine did not create the database tables. The database is MySQL.

由于某种原因,当我将一个新的链接实体持久化并刷新到链接表(见下文)时,外键字段(container_id)将被设置到NULL。但是,如果从ManyToOne(targetEntity =Shepherd\Navigation\Domain\Container\Model,inversedBy =links)行除去@符号,则外键字段将被正确填充。

For some reason, when I persist and flush a new link entity to the link table (see below) the foreign key field (container_id) gets set to NULL. However, if the '@' symbol is removed from the 'ManyToOne(targetEntity="Shepherd\Navigation\Domain\Container\Model", inversedBy="links")' line, the foreign key field is populated properly.

由于当@符号被删除时,实体被正确地添加到数据库中,所以OneToMany关系有一些问题。

Since the entity is added properly to the database when the '@' symbol is removed, there is something wrong with the OneToMany relationship somewhere.

例如,如果我有一个名为$ link的链接模型(请参阅下面的伪代码)...

For example, if I have a link model named $link (see pseudo-code below)...

 $link (Shepherd\Navigation\Domain\Link\Model) 
    {
        id:   ''      // auto generated value
        cid:  23      // the foreign key value
        label: test   
        uri: test.com 
        ...           // other values not listed here for brevity
    }

...当新的链接模型被持久化并且实体管理器被刷新时,来自链接中新插入的行的container_id(外键)值(shepherd_navigation_link)表是NULL。

...when the new link model is persisted and the entity manager is flushed, the container_id (foreign key) value from the newly inserted row in the link (shepherd_navigation_link) table is NULL.

    $em // Assume $em is the Entity Manager
    $em->persist($link);
    $em->flush();

    // The container_id in the newly added row in the 
    // link table (shepherd_navigation_link) is NULL 

链接表模式:

CREATE TABLE `shepherd_navigation_link` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `container_id` int(10) unsigned DEFAULT NULL,
  `node_id` int(10) unsigned DEFAULT NULL,
  `parent_id` int(10) unsigned DEFAULT NULL,
  `label` varchar(100) NOT NULL,
  `options` text,
  `events` text,
  `privilege` varchar(100) NOT NULL,
  `resource` varchar(100) DEFAULT NULL,
  `uri` varchar(300) NOT NULL,
  `visible` int(10) unsigned DEFAULT '1',
  PRIMARY KEY (`id`),
  KEY `container_id` (`container_id`)
) ENGINE=InnoDB
ALTER TABLE `shepherd_navigation_link` ADD FOREIGN KEY (container_id) REFERENCES shepherd_navigation_container(id)

链接实体模型:

/**
 * @Entity
 * @Table(name="shepherd_navigation_link")
 */
class
{
    /** 
     * @Id 
     * @Column(type="integer")
     * @GeneratedValue 
     */
     protected $id;

    /** 
     * @Column(name="container_id", type="integer", nullable=false)
     */
     protected $cid;

    /** 
     * @Column(name="node_id", type="integer")
     */
    protected $nid;

    /** 
     * @Column(name="parent_id", type="integer", nullable=false)
     */
    protected $pid;

    /** 
     * @Column
     */
    protected $label;

    /** 
     * @Column(nullable=true)
     */
    protected $options;

    /** 
     * @Column(nullable=true)
     */
    protected $events;

    /** 
     * @Column
     */
    protected $privilege;

    /** 
     * @Column(nullable=true)
     */
    protected $resource;

    /** 
     * @Column
     */
    protected $uri;

    /** 
     * @Column(type="integer", nullable=true)
     */
    protected $visible;

    /**
     * @OneToMany(targetEntity="Model", mappedBy="parent")
     */
    private $children;

    /**
     * @ManyToOne(targetEntity="Model", inversedBy="children")
     */
    private $parent;

    /**
     *) @ManyToOne(targetEntity="Shepherd\Navigation\Domain\Container\Model", inversedBy="links"
     */
    private $container;

    /**
     * @OneToOne(targetEntity="Shepherd\Navigation\Domain\Link\Position", inversedBy="link")
     */
    private $node;

    public function __construct()
    {
        $this->children = new \Doctrine\Common\Collections\ArrayCollection();   
    }

    /** Accessors and Mutators excluded for brevity **/
}

注意:受保护的属性$ cid映射到上面的container_id列。

Note: the protected property $cid maps to the container_id column above.

容器表模式:

CREATE TABLE `shepherd_navigation_container` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `description` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB

容器实体模型:

/**
 * @Entity
 * @Table(name="shepherd_navigation_container")
 */
class Model
{
    /** 
     * @Id 
     * @Column(type="integer")
     * @GeneratedValue 
     */
    protected $id;

    /** 
     * @Column
     */
    protected $name;

    /** 
     * @Column(nullable=true)
     */
    protected $description;

    /**
     * @OneToMany(targetEntity="Shepherd\Navigation\Domain\Link\Model", mappedBy="container")
     */
    private $links;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->links = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /** Accessors and Mutators excluded for brevity **/
}

我缺少什么?我做错了什么?

What am I missing? What am I doing wrong?

推荐答案

我想出了这个问题(通过阅读文档 http://www.doctrine-project.org/docs/orm/ 2.0 / EN /教程/工具入门的XML-edition.html )。事实证明,实际上有一些问题。

I figured out the problem (by reading the documentation http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html). It turns out there were actually a few problems.

问题1 =>我没有提供设置容器变量的方法。

Problem 1 => I did not provide a method to set the container variable.

// Inside the Link Entity class...

public function setContainer($container)
{
    $this->container = $container;
}

问题2 =>我没有设置容器值。错误的是,我认为Doctrine 2在内部做了这个,但是我发现容器变量需要在冲洗之前设置。

Problem 2 => I did not set the container value. In error, I thought Doctrine 2 did this internally, but I found out the container variable needs to be set prior to flushing.

我的愚蠢的监督。 >

Foolish oversight on my part.

$link = new Link();
$link->setContainer($container);

// $em is the Entity Manager
$em->persist($link);
$em->flush();

问题3 =>容器($ container)需要在冲洗之前保持或@需要更改的容器实体上的OneToMany定义。我选择更新容器实体定义。看看这里( http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#transitive-persistence-cascade-operations )了解更多信息。

Problem 3 => The container ($container) needed to either be persisted prior to flushing or the @OneToMany definition on the container entity needed to change. I chose to update the container entity definition. Take a look here (http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#transitive-persistence-cascade-operations) for more information.

// Inside the Container Entity class...
/**
 * @OneToMany(targetEntity="Shepherd\Navigation\Domain\Link\Model", mappedBy="container", cascade={"persist"})
 */

进行这些更改并删除链接实体类中的@OneToOne节点关系(原来我不需要它),一切都正常。我希望这有助于某人。

After making these changes and removing the @OneToOne node relationship in the link entity class (turns out I didn't need it), everything worked fine. I hope this helps someone.

这篇关于doctrine2 OneToMany关系将NULL作为外键插入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆