2011-03-16 3 views
5

저는 ZendFramework 1.11.2 내에서 Doctrine 2를 ORM으로 사용하여 양방향 OneToMany 관계를가집니다.doctrine2 OneToMany 관계가 외래 키로 NULL을 삽입합니다.

참고 : Doctrine은 데이터베이스 테이블을 만들지 않았습니다. 데이터베이스는 MySQL입니다.

어떤 이유로, 새 링크 엔티티를 유지하고 링크 테이블에 플러시 할 때 (아래 참조) 외래 키 필드 (container_id)가 NULL로 설정됩니다. 그러나 'ManyToOne (targetEntity = "Shepherd \ Navigation \ Domain \ Container \ Model", inversedBy = "links")'행에서 '@'기호가 제거되면 외래 키 필드가 제대로 채워집니다.

'@'기호가 제거되면 엔티티가 데이터베이스에 제대로 추가되므로 OneToMany 관계에 어딘가에 문제가 있습니다. 나는 $ 링크라는 이름의 링크 모델이있는 경우

예를 들어, (아래 의사 코드 참조)

$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 
    } 

... 새로운 링크 모델은 지속되고 엔티티 관리자가 플러시 될 때, 링크 (shepherd_navigation_link) 테이블에 새로 삽입 된 행의 container_id (외래 키) 값이 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 **/ 
} 

참고 : 위의 container_id 컬럼으로 보호 된 속성 $의 CID지도.

컨테이너 테이블 스키마 :

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 **/ 
} 

나는 무엇을 놓치고? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

+0

연관 매핑에서 대상 엔터티에 대한 전체 경로가 필요하다고 생각하지 않습니다. 어떤 사람에게는 전체 경로가 있고 다른 사람에게는 엔티티 이름이있는 것처럼 보입니다. 그게 문제의 원인인지는 모르겠지만 당신이 볼 수있는 것입니다. –

+0

감사합니다. Jeremy, 당신 말이 맞아요. 모델 명명에 일관성이 없습니다. 그러나 문제는 여전히 지속됩니다. – user175590

답변

5

문제점을 발견했습니다 (문서 http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/getting-started-xml-edition.html 참조). 실제로 몇 가지 문제가 발생했습니다.

문제 1 => 컨테이너 변수를 설정하는 방법을 제공하지 않았습니다.

// Inside the Link Entity class... 

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

문제 2 => 컨테이너 값을 설정하지 않았습니다. 실수로 Doctrine 2는 내부적으로 이것을 수행했다고 생각했지만 플러시하기 전에 컨테이너 변수를 설정해야한다는 것을 알았습니다.

내 역할에 대한 어리석은 감시. 종래 플러싱하거나 변경하는 데 필요한 용기 엔티티에 @OneToMany 정의를 유지해야 하나에 필요한

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

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

문제 3 => 용기 ($ 용기). 컨테이너 엔티티 정의를 업데이트하기로했습니다. 자세한 내용은 여기 (http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#transitive-persistence-cascade-operations)를보십시오.

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

이러한 변경을하고 링크 엔티티 클래스에 @OneToOne 노드 관계를 (밝혀 내가 필요하지 않았다) 제거한 후, 다 괜찮 았는데. 나는 이것이 누군가를 돕기를 바랍니다.

관련 문제