Getting fixtures to load after creating a join table entity

别说谁变了你拦得住时间么 提交于 2020-01-06 08:45:09

问题


I recently asked the following question:

Many to Many, One to Many or Many to One

After doing the updates suggested by @inanzzz my database looks great now however my fixtures seem to not work. I get the following error when trying to load them:

[Symfony\Component\Debug\Exception\ContextErrorException]
Catchable Fatal Error: Argument 1 passed to BBQ\Charcoal\WebsiteBundle\Enti
ty\Templates::addModule() must be an instance of BBQ\Charcoal\WebsiteBundle
\Entity\TemplateModules, instance of Proxies\__CG__\BBQ\Charcoal\WebsiteBun
dle\Entity\Modules given, called in /Users/alexward/dev/symphony/symphony20
14/www/src/BBQ/Charcoal/WebsiteBundle/DataFixtures/ORM/TemplateFixtures.php
 on line 19 and defined in /Users/alexward/dev/symphony/symphony2014/www/sr
c/BBQ/Charcoal/WebsiteBundle/Entity/Templates.php line 141

Line 141 of templates.php is:

/**
 * Add modules
 *
 * @param \BBQ\Charcoal\WebsiteBundle\Entity\TemplateModules $modules
 * @return Templates
 */
public function addModule(\BBQ\Charcoal\WebsiteBundle\Entity\TemplateModules $modules)
{
    $this->modules[] = $modules;

    return $this;
}

Here are my entity classes:

class Modules
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=10)
 */
protected $type;

 /**
 * @ORM\Column(type="string")
 */
protected $name;

 /**
 * @ORM\Column(type="string")
 */
protected $friendly_name;

/**
 * @ORM\Column(type="text")
 */
protected $description;

/**
 * @ORM\Column(type="integer")
 */
protected $max_limit;

/**
 * @ORM\Column(type="integer")
 */
protected $min_limit;

/**
 * @var ArrayCollection
 * @ORM\OneToMany(targetEntity="TemplateModules", mappedBy="modules")
 */
private $templates;

/**
 * @var ArrayCollection
 * @ORM\OneToMany(targetEntity="Content", mappedBy="modules")
 */
private $content;

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


class TemplateModules {
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

 /**
 * @ORM\ManyToOne(targetEntity="Templates", inversedBy="modules")
 */
protected $templates;

/**
 * @ORM\ManyToOne(targetEntity="Modules", inversedBy="templates")
 */
protected $modules;

/**
 * @ORM\Column(type="integer")
 */
private $order_by;
}

class Templates {
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

 /**
 * @ORM\Column(type="string")
 */
protected $name;

 /**
 * @ORM\Column(type="string")
 */
protected $friendly_name;

/**
 * @var ArrayCollection
 * @ORM\OneToMany(targetEntity="Pages", mappedBy="template")
 */
private $pages;

/**
 * @ORM\OneToMany(targetEntity="TemplateModules", mappedBy="templates")
 **/
protected $modules;

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

Here are my fixtures for the two sections:

Modules:

<?php

namespace BBQ\Charcoal\WebsiteBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use BBQ\Charcoal\WebsiteBundle\Entity\TemplateModules;
use BBQ\Charcoal\WebsiteBundle\Entity\Modules;

class ModulesFixtures extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $manager)
{
    $module1 = new Modules();
    $module1->setName('info_box_three_up');
    $module1->setFriendlyName('Information Module (3 to a row)');
    $module1->setDescription('Information Module (3 to a row)');
    $module1->setMinLimit(1);
    $module1->setMaxLimit(1);
    $module1->setType('row');
    $manager->persist($module1);

    $module2 = new Modules();
    $module2->setName('cta_single_line_text');
    $module2->setFriendlyName('Single line CTA with button');
    $module2->setDescription('Single line CTA with button');
    $module2->setMinLimit(1);
    $module2->setMaxLimit(1);
    $module2->setType('row');
    $manager->persist($module2);

    $module3 = new Modules();
    $module3->setName('video');
    $module3->setFriendlyName('Video panel');
    $module3->setDescription('Video panel');
    $module3->setMinLimit(2);
    $module3->setMaxLimit(2);
    $module3->setType('row');
    $manager->persist($module3);

    $module4 = new Modules();
    $module4->setName('stories_two_up');
    $module4->setFriendlyName('Stories (2)');
    $module4->setDescription('Stories (2)');
    $module4->setMinLimit(2);
    $module4->setMaxLimit(2);
    $module4->setType('row');
    $manager->persist($module4);

    $module5 = new Modules();
    $module5->setName('cta_multi_line_text');
    $module5->setFriendlyName('Multiple line CTA with button');
    $module5->setDescription('Multiple line CTA with button');
    $module5->setMinLimit(1);
    $module5->setMaxLimit(1);
    $module5->setType('row');
    $manager->persist($module5);

    $manager->flush();

    $this->addReference('module-1', $module1);
    $this->addReference('module-2', $module2);
    $this->addReference('module-3', $module3);
    $this->addReference('module-4', $module4);
    $this->addReference('module-5', $module5);
}

public function getOrder()
{
    return 1;
}

}

Templates:

<?php

namespace BBQ\Charcoal\WebsiteBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use BBQ\Charcoal\WebsiteBundle\Entity\Templates;
use BBQ\Charcoal\WebsiteBundle\Entity\Modules;
use BBQ\Charcoal\WebsiteBundle\Entity\TemplateModules;

class TemplatesFixtures extends AbstractFixture implements OrderedFixtureInterface
{
public function load(ObjectManager $manager)
{
    $template1 = new Templates();
    $template1->setName('T1_Homepage');
    $template1->setFriendlyName('Homepage Template');
    $template1->addModule($this->getReference('module-1'));
    $template1->addModule($this->getReference('module-2'));
    $template1->addModule($this->getReference('module-3'));
    $template1->addModule($this->getReference('module-4'));
    $template1->addModule($this->getReference('module-5'));

    $manager->persist($template1);

    $manager->flush();

    $this->addReference('template-1', $template1);
}

public function getOrder()
{
    return 2;
}
}

回答1:


This is how it should be because your table/method/entity is expecting a specific object rather than something else like integer, another object so on.

->addModule(instanbe of TemplateModules is expected here)
but you have given
->addModule(instance of Modules is expected here)

If you say it should definitely be $this->modules[] = $modules; then you probably have set relationships wrong or something similar. You might need to check the relationships.

EDIT:

Look at the difference between you code and mine. You don't have JoinColumn bit in your annotations. I used Student and Course as an example.

class Student
class Modules
{
    /**
     * @ORM\OneToMany(targetEntity="TemplateModules", mappedBy="modules")
     * 
     * @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="studentMap")
     */
    private $templates;
    protected $studentInverse;

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

    }
}

class StudentCourse
class TemplateModules
{
    /**
     * @ORM\ManyToOne(targetEntity="Modules", inversedBy="templates")
     * 
     * @ORM\ManyToOne(targetEntity="Student", inversedBy="studentInverse")
     * @ORM\JoinColumn(name="student", referencedColumnName="id")
     */
    protected $modules;
    protected $studentMap;

     /**
     * @ORM\ManyToOne(targetEntity="Templates", inversedBy="modules")
     * 
     * @ORM\ManyToOne(targetEntity="Course", inversedBy="courseInverse")
     * @ORM\JoinColumn(name="course", referencedColumnName="id")
     */
    protected $templates;
    protected $courseMap;
}


class Course
class Templates
{
    /**
     * @ORM\OneToMany(targetEntity="TemplateModules", mappedBy="templates")
     * 
     * @ORM\OneToMany(targetEntity="StudentCourse", mappedBy="courseMap")
     **/
    protected $modules;
    protected $courseInverse;

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

EDIT 2:

Sound like this is what is happening in your case:

$studentId = 1;
$courseId = 1;

$studentCourse = new StudentCourse();
$studentCourse->setStudentMap($studentId);
$studentCourse->setCourseMap($courseId);

$em = $this->getDoctrine()->getManager();
$em->persist($studentCourse);
$em->flush();

Above will not work! Below is how it should be because your middle table is expecting an object rather than something else like integer so on.

->addModule(instance of TemplateModules is expected here)
but you have given
->addModule(instance of Modules)

EDIT 3:

Your fixtures looks a bit complex to me. Simplified Example Fixtures. Do things one by one (little bit) so that you can easily debug.

$em = $this->getDoctrine()->getManager();

$modules = new Modules();
$modules->.....
$em->persist($modules);


$templates = new Templates();
$templates->.....
$em->persist($templates);


$templateModules = new TemplateModules();
$templateModules->setModules($modules);
$templateModules->setTemplates($templates);
$em->persist($templateModules);

$em->flush();


来源:https://stackoverflow.com/questions/26575174/getting-fixtures-to-load-after-creating-a-join-table-entity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!