Doctrine Symfony one-many不工作,但很多人

时间:2013-08-13 21:01:17

标签: symfony doctrine one-to-many many-to-one behat

好的,这是树木问题的真正原因。

我正在尝试使用一对多到多个实体结构。 我有三个实体

  • 项目(有ID和名称)
  • 研究员(有身份证和姓名)
  • 项目研究员(具有ID,项目ID,研究员ID和研究员在该项目中的作用)

因此它们编码如下(使用注释)

namespace ons\Bundle\Geneapro\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * Project
 *
 * @ORM\Table(name="gpt_project")
 * @ORM\Entity
 */
class Project
{
    /**
     * @var string
     *
     * @ORM\Column(name="Name", type="string", nullable=false)
     */
    private $name;

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

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity=" ResearcherProject", mappedBy="project")
     */
    private $researcherprojects;

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

    /**
     * Set name
     *
     * @param string $name
     * @return Project
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Add researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     * @return Project
     */
    public function addResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects[] = $researcherprojects;
        return $this;
    }

    /**
     * Remove researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     */
    public function removeResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects->removeElement($researcherprojects);
    }

    /**
     * Get researcherprojects
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getResearcherprojects()
    {
        return $this->researcherprojects;
    }
}

研究员几乎完全相同

namespace ons\Bundle\Geneapro\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * Researcher
 *
 * @ORM\Table(name="gpt_researcher")
 * @ORM\Entity
 */
class Researcher
{
    /**
     * @var string
     *
     * @ORM\Column(name="Name", type="string", nullable=false)
     */
    private $name;

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

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity=" ResearcherProject", mappedBy="researcher")
     */
    private $researcherprojects;

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

    /**
     * Set name
     *
     * @param string $name
     * @return Researcher
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Add researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     * @return Researcher
     */
    public function addResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects[] = $researcherprojects;
        return $this;
    }

    /**
     * Remove researcherprojects
     *
     * @param ResearcherProject $researcherprojects
     */
    public function removeResearcherproject(ResearcherProject $researcherprojects)
    {
        $this->researcherprojects->removeElement($researcherprojects);
    }

    /**
     * Get researcherprojects
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getResearcherprojects()
    {
        return $this->researcherprojects;
    }
}

最后研究员项目

namespace ons\Bundle\Geneapro\DataBundle\Entity;
use Doctrine\ORM\Mapping as ORM;

/**
 * ResearcherProject
 *
 * @ORM\Table(name="gpt_researcher_project")
 * @ORM\Entity
 */
class ResearcherProject
{
    /**
     * @var string
     *
     * @ORM\Column(name="Role", type="string", nullable=false)
     */
    private $role;

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

    /**
     * @var Researcher
     *
     * @ORM\ManyToOne(targetEntity="Researcher", inversedBy="researcherprojects")
     */
    private $researcher;

    /**
     * @var Project
     *
     * @ORM\ManyToOne(targetEntity="Project", inversedBy="researcherprojects")
     */
    private $project;

    /**
     * Set role
     *
     * @param string $role
     * @return ResearcherProject
     */
    public function setRole($role)
    {
        $this->role = $role;
        return $this;
    }

    /**
     * Get role
     *
     * @return string 
     */
    public function getRole()
    {
        return $this->role;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set researcher
     *
     * @param Researcher $researcher
     * @return ResearcherProject
     */
    public function setResearcher(Researcher $researcher = null)
    {
        $this->researcher = $researcher;
        return $this;
    }

    /**
     * Get researcher
     *
     * @return Researcher 
     */
    public function getResearcher()
    {
        return $this->researcher;
    }

    /**
     * Set project
     *
     * @param Project $project
     * @return ResearcherProject
     */
    public function setProject(Project $project = null)
    {
        $this->project = $project;
        return $this;
    }

    /**
     * Get project
     *
     * @return Project 
     */
    public function getProject()
    {
        return $this->project;
    }
}

正如预期的那样产生以下SQL

CREATE TABLE gpt_project (id INT AUTO_INCREMENT NOT NULL, Name VARCHAR(255) NOT NULL, Description VARCHAR(255) DEFAULT NULL, ClientData LONGTEXT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

CREATE TABLE gpt_researcher (id INT AUTO_INCREMENT NOT NULL, Name VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

CREATE TABLE gpt_researcher_project (id INT AUTO_INCREMENT NOT NULL, researcher_id INT DEFAULT NULL, project_id INT DEFAULT NULL, Role VARCHAR(255) NOT NULL, INDEX IDX_5E15A9AEC7533BDE (researcher_id), INDEX IDX_5E15A9AE166D1F9C (project_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

ALTER TABLE gpt_researcher_project ADD CONSTRAINT FK_5E15A9AEC7533BDE FOREIGN KEY (researcher_id) REFERENCES gpt_researcher (id);

ALTER TABLE gpt_researcher_project ADD CONSTRAINT FK_5E15A9AE166D1F9C FOREIGN KEY (project_id) REFERENCES gpt_project (id);

到目前为止,我现在正在使用Behat编写我的场景,并且我有以下功能定义。

Feature: ResearcherProject
  In order to track who did research
  As the Data Bundle
  I need to be able to create and manage ResearcherProjects

Background:
    Given there is no "ResearcherProject" in database
    And there is no "Project" in database
    And there is no "Researcher" in database

Scenario: A ResearcherProject joins Researchers to Projects
    When I create a Project "New Project"  
    And I create a Researcher "Researcher" 
    And I add Researcher "Researcher" to Project "New Project" as "Lead"    
    Then Researcher Project "1" joins "Researcher" to Project "New Project" as "Lead"    
    And Project "New Project" is Researched By "1" Researcher 
    And Researcher "Researcher" Researches "1" Project

数据很好地加载到数据库中,并且将项目链接到角色中的研究员的研究员项目的测试工作,但是发生以下情况

01. Failed asserting that actual size 0 matches expected size 1. 
    In step `And Project "New Project" is Researched By "1" Researcher'.

进行测试的两个函数是

/**
 * @Then /^Researcher Project "([^"]*)" joins "([^"]*)" to Project "([^"]*)" as "([^"]*)"$/
 */
public function researcherProjectJoinsToProjectAs($ResearcherProjectID, $ResearcherName, $ProjectName, $Role)
{
    $rp=$this->getEntityByID("ResearcherProject", $ResearcherProjectID);
    assertEquals($ResearcherProjectID, $rp->getID());
    assertEquals($ResearcherName,$rp->getResearcher()->getName());
    assertEquals($ProjectName,$rp->getProject()->getName());                
    assertEquals($Role,$rp->getRole());
}

/**
 * @Then /^Project "([^"]*)" is Researched By "([^"]*)" Researcher$/
 */
public function projectIsResearchedByResearcher($ProjectName, $expectedCount)
{        
    $project=$this->getEntityByName("Project", $ProjectName);
    assertCount($expectedCount*1, $project->getResearcherprojects());
}

GetEntityByNameGetEntityByID按照他们的说法行事。

我做错了什么,为什么我可以从内到外而不是从外面工作? 这已经困扰了我两天,所以任何帮助都欢迎,我确信这是一个非常简单但它超出了我。

修改

所以我想我可以开始看到树木,但现在这是一个稍微不同的问题! 这应该是一个无头捆绑,所以我没有提供任何视图或控制器。添加了一个树枝模板,并运行它弹出链接。

因此必须是导致它的测试中的行为。

2 个答案:

答案 0 :(得分:0)

assertEquals($expectedCount*1, $project->getResearcherprojects());

$project->getResearcherprojects()返回ResearcherProject的ArrayCollection。如果你想要计算它们,你必须这样做:

assertEquals($expectedCount*1, $project->getResearcherprojects()->count());

答案 1 :(得分:0)

确定,

有了twig方法工作后,我想知道如果我从数据库中取出它是否可行,所以我将我的方案改为

Feature: ResearcherProject
  In order to track who did research
  As the Data Bundle
  I need to be able to create and manage Researchers


Scenario: A ResearcherProject joins Researchers to Projects
    Then Researcher Project "1" joins "Researcher" to Project "New Project" as "Lead"    
    And Project "New Project" is Researched By "1" Researcher 
    And Researcher "Researcher" Researches "1" Project 

宾果全部通过,所以它看起来像一个缓存问题。实体经理显然正在返回它的项目和研究员的版本,而且还没有更新

所以问题出在这里......

/**
 * @Given /^I add Researcher "([^"]*)" to Project "([^"]*)" as "([^"]*)"$/
 */
public function iAddResearcherToProjectAs($ResearcherName, $ProjectName, $Role)
{

    $em = $this->getEntityManager();


    //Get Researcher
    $researcher=$em->getRepository('onsGeneaproDataBundle:Researcher')
                   ->findOneByName($ResearcherName);
    //Get Project
    $project=$em->getRepository('onsGeneaproDataBundle:Project')
                ->findOneByName($ProjectName);

    $researcherproject = new \ons\Bundle\Geneapro\DataBundle\Entity\ResearcherProject();
    $researcherproject->setRole($Role);
    $researcherproject->setProject($project);        
    $researcherproject->setResearcher($researcher);

//*** The following Two Lines make it work ***//
    $project->addResearcherproject($researcherproject);//Why dose this not happen automaticaly?
    $researcher->addResearcherproject($researcherproject);//Why dose this not happen automaticaly?
//*** ***//

    $em->persist($researcherproject);
    $em->flush();
}

如果我进行反向更新并将ResearcherProject添加到Researcher和Project,则所有测试都会通过。

但是这引出了以下问题

  1. 为什么Projecct and Researcher没有收到更新?
  2. 或如何在更新实体后强制实体管理器清除其缓存。