我正在测试Symfony2和Doctrin2中Job
实体和Category
实体之间的级联持续存在。
这是我的Category
实体:
<?php
namespace Ibw\JobeetBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Ibw\JobeetBundle\Entity\Affiliate;
use Ibw\JobeetBundle\Entity\Job;
use Ibw\JobeetBundle\Utils\Jobeet;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="Ibw\JobeetBundle\Repository\CategoryRepository")
* @ORM\Table(name="categories")
* @ORM\HasLifecycleCallbacks
*/
class Category
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255, unique=true)
*/
protected $name;
/**
* @ORM\OneToMany(targetEntity="Job", mappedBy="category", cascade={"persist"})
*/
protected $jobs;
/**
* @ORM\ManyToMany(targetEntity="Affiliate", mappedBy="categories")
*/
protected $affiliates;
/**
* @ORM\Column(type="string", length=255, unique=true)
*/
protected $slug;
/**
* Constructor
*/
public function __construct()
{
$this->jobs = new ArrayCollection();
$this->affiliates = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Add jobs
*
* @param Job $jobs
* @return Category
*/
public function addJob(Job $jobs)
{
$this->jobs[] = $jobs;
return $this;
}
/**
* Remove jobs
*
* @param Job $jobs
*/
public function removeJob(Job $jobs)
{
$this->jobs->removeElement($jobs);
}
/**
* Get jobs
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getJobs()
{
return $this->jobs;
}
/**
* Add affiliates
*
* @param Affiliate $affiliates
* @return Category
*/
public function addAffiliate(Affiliate $affiliates)
{
$this->affiliates[] = $affiliates;
return $this;
}
/**
* Remove affiliates
*
* @param Affiliate $affiliates
*/
public function removeAffiliate(Affiliate $affiliates)
{
$this->affiliates->removeElement($affiliates);
}
/**
* Get affiliates
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAffiliates()
{
return $this->affiliates;
}
/**
* Set slug
*
* @param string $slug
* @return Category
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function setSlugValue()
{
$this->setSlug(Jobeet::slugify($this->getName()));
}
}
这里是级联持续存在的部分:
/**
* @ORM\OneToMany(targetEntity="Job", mappedBy="category", cascade={"persist"})
*/
protected $jobs;
现在,当我尝试使用此测试进行测试时:
public function testAddJobToCategory()
{
$job = new Job();
$job->setType('flexible-time');
$job->setCompany('Sensio Labs');
$job->setLogo('sensio-labs.gif');
$job->setUrl('http://www.sensiolabs.com/');
$job->setPosition('Web Developer');
$job->setLocation('Paris, France');
$job->setDescription('You\'ve already developed websites with symfony and you want to work with Open-Source technologies. You have a minimum of 3 years experience in web development with PHP or Java and you wish to participate to development of Web 2.0 sites using the best frameworks available.');
$job->setHowToApply('Send your resume to fabien.potencier [at] sensio.com');
$job->setIsPublic(true);
$job->setIsActivated(true);
$job->setToken('job');
$job->setEmail('job@example.com');
$job->setExpiresAt(new \DateTime('+30 days'));
$category = $this->em->createQueryBuilder('c')
->select('c')
->from('IbwJobeetBundle:Category', 'c')
->where('c.id = 1')
->getQuery()
->getSingleResult();
$category->addJob($job);
$this->em->persist($category);
$this->em->flush();
$jobFromQuery = $this->em->createQueryBuilder('j')
->select('j')
->from('IbwJobeetBundle:Job', 'j')
->where('j.type = :type')
->setParameter('type', 'flexible-time')
->setMaxResults(1)
->setFirstResult(1)
->getQuery()
->getSingleResult();
$this->assertEquals(1, $jobFromQuery->getCategory()->getId());
}
当我运行此测试时,我收到此错误:
PHP致命错误:在非对象上调用成员函数getId()
所以我认为它在$jobFromQuery->getCategory()->getId()
部分。 getCategory()
未设置或其他内容。
答案 0 :(得分:0)
此学说文档http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html说:
Doctrine只会检查协会的拥有方是否有变更。
要完全理解这一点,请记住在对象世界中如何维护双向关联。关联的每一侧有2个引用,这两个引用都代表相同的关联,但可以彼此独立地改变。当然,在正确的应用程序中,双向关联的语义由应用程序开发人员正确维护(这是他的职责)。 Doctrine需要知道这两个内存引用中的哪一个应该是持久化的,哪些不是。这就是拥有/反向概念主要用于。
忽略仅对关联的反面进行的更改。确保更新双向关联的两面(或至少从Doctrine的角度更新所有方)
双向关联的拥有方是在确定关联状态时“侧面”的Doctrine“查看”,因此是否有任何事情可以更新数据库中的关联
在您的代码中,您只需执行$category->addJob($job);
,因此您可以在反面设置关联。作为被忽略的文档,您至少应该先$job->setCategory($category)
。