1

I'm lost in a complexe relation (for me). I've a entity project for an entity client and you can attach users to a project. When i try to add a project without users, no problem. But, when i try to add a project and users Sf2 display this error :

Entity of type Intranet\IntranetBundle\Entity\ProjectUser is missing an assigned ID for field 'project'. The identifier generation strategy for this entity requires the ID field to be populated before EntityManager#persist() is called. If you want automatically generated identifiers instead you need to adjust the metadata mapping accordingly.

I'm understand it's angry because the project_id is null. But i don't know why it's null.

My Project.php

namespace Intranet\IntranetBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Project
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Intranet\IntranetBundle\Entity\ProjectRepository")
 */
class Project
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     * @Assert\NotBlank(
     *      message = "The field cannot be empty" 
     * )
     */
    private $name;

    /**
     * @Gedmo\Slug(fields={"name"})
     * @ORM\Column(length=255, unique=true)
     */
    private $slug;

    /**
     * @var string
     *
     * @ORM\Column(name="contact_client", type="text", nullable=true)
     */
    private $contactClient;

    /**
     * @var string
     *
     * @ORM\Column(name="technologies", type="string", length=255, nullable=true)
     */
    private $technologies;

    /**
     * @var string
     *
     * @ORM\Column(name="languages", type="string", length=255, nullable=true)
     */
    private $languages;

    /**
     * @var string
     *
     * @ORM\Column(name="extern", type="text", nullable=true)
     */
    private $extern;

    /**
     * @var string
     *
     * @ORM\Column(name="url_prod", type="string", length=255, nullable=true)
     */
    private $urlProd;

    /**
     * @var string
     *
     * @ORM\Column(name="url_staging", type="text", nullable=true)
     */
    private $urlStaging;

    /**
     * @var string
     *
     * @ORM\Column(name="url_dev", type="text", nullable=true)
     */
    private $urlDev;

    /**
     * @var string
     *
     * @ORM\Column(name="hosting_company", type="string", length=255, nullable=true)
     */
    private $hostingCompany;

    /**
     * @var string
     *
     * @ORM\Column(name="hosting_type", type="string", length=255, nullable=true)
     */
    private $hostingType;

    /**
     * @var string
     *
     * @ORM\Column(name="hosting_manager", type="text", nullable=true)
     */
    private $hostingManager;

    /**
     * @var string
     *
     * @ORM\Column(name="ssh", type="text", nullable=true)
     */
    private $ssh;

    /**
     * @var string
     *
     * @ORM\Column(name="ftp", type="text", nullable=true)
     */
    private $ftp;

    /**
     * @var string
     *
     * @ORM\Column(name="db", type="text", nullable=true)
     */
    private $db;

    /**
     * @var string
     *
     * @ORM\Column(name="emails", type="text", nullable=true)
     */
    private $emails;

    /**
     * @var string
     *
     * @ORM\Column(name="cms", type="text", nullable=true)
     */
    private $cms;

    /**
     * @var string
     *
     * @ORM\Column(name="web_services", type="text", nullable=true)
     */
    private $webServices;

    /**
     * @var string
     *
     * @ORM\Column(name="comment", type="text", nullable=true)
     */
    private $comment;

    /**
     * @ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Client", inversedBy="projects")
     * @ORM\JoinColumn(nullable=false)
     */
    private $client;

    /**
     * @ORM\OneToMany(targetEntity="Intranet\IntranetBundle\Entity\ProjectUser", mappedBy="project", cascade={"persist"})
     */
    private $projectUsers;

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

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

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

    /**
     * Set slug
     *
     * @param string $slug
     * @return Client
     */
    public function setSlug($slug)
    {
        $this->slug = $slug;

        return $this;
    }

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

    /**
     * Set contactClient
     *
     * @param string $contactClient
     * @return Project
     */
    public function setContactClient($contactClient)
    {
        $this->contactClient = $contactClient;

        return $this;
    }

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

    /**
     * Set technologies
     *
     * @param string $technologies
     * @return Project
     */
    public function setTechnologies($technologies)
    {
        $this->technologies = $technologies;

        return $this;
    }

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

    /**
     * Set languages
     *
     * @param string $languages
     * @return Project
     */
    public function setLanguages($languages)
    {
        $this->languages = $languages;

        return $this;
    }

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

    /**
     * Set extern
     *
     * @param string $extern
     * @return Project
     */
    public function setExtern($extern)
    {
        $this->extern = $extern;

        return $this;
    }

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

    /**
     * Set urlProd
     *
     * @param string $urlProd
     * @return Project
     */
    public function setUrlProd($urlProd)
    {
        $this->urlProd = $urlProd;

        return $this;
    }

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

    /**
     * Set urlStaging
     *
     * @param string $urlStaging
     * @return Project
     */
    public function setUrlStaging($urlStaging)
    {
        $this->urlStaging = $urlStaging;

        return $this;
    }

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

    /**
     * Set urlDev
     *
     * @param string $urlDev
     * @return Project
     */
    public function setUrlDev($urlDev)
    {
        $this->urlDev = $urlDev;

        return $this;
    }

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

    /**
     * Set hostingCompany
     *
     * @param string $hostingCompany
     * @return Project
     */
    public function setHostingCompany($hostingCompany)
    {
        $this->hostingCompany = $hostingCompany;

        return $this;
    }

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

    /**
     * Set hostingType
     *
     * @param string $hostingType
     * @return Project
     */
    public function setHostingType($hostingType)
    {
        $this->hostingType = $hostingType;

        return $this;
    }

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

    /**
     * Set hostingManager
     *
     * @param string $hostingManager
     * @return Project
     */
    public function setHostingManager($hostingManager)
    {
        $this->hostingManager = $hostingManager;

        return $this;
    }

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

    /**
     * Set ssh
     *
     * @param string $ssh
     * @return Project
     */
    public function setSsh($ssh)
    {
        $this->ssh = $ssh;

        return $this;
    }

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

    /**
     * Set ftp
     *
     * @param string $ftp
     * @return Project
     */
    public function setFtp($ftp)
    {
        $this->ftp = $ftp;

        return $this;
    }

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

    /**
     * Set db
     *
     * @param string $db
     * @return Project
     */
    public function setDb($db)
    {
        $this->db = $db;

        return $this;
    }

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

    /**
     * Set emails
     *
     * @param string $emails
     * @return Project
     */
    public function setEmails($emails)
    {
        $this->emails = $emails;

        return $this;
    }

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

    /**
     * Set cms
     *
     * @param string $cms
     * @return Project
     */
    public function setCms($cms)
    {
        $this->cms = $cms;

        return $this;
    }

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

    /**
     * Set webServices
     *
     * @param string $webServices
     * @return Project
     */
    public function setWebServices($webServices)
    {
        $this->webServices = $webServices;

        return $this;
    }

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

    /**
     * Set comment
     *
     * @param string $comment
     * @return Project
     */
    public function setComment($comment)
    {
        $this->comment = $comment;

        return $this;
    }

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

    /**
     * Set client
     *
     * @param \Intranet\IntranetBundle\Entity\Client $client
     * @return Project
     */
    public function setClient(\Intranet\IntranetBundle\Entity\Client $client)
    {
        $this->client = $client;

        return $this;
    }

    /**
     * Get client
     *
     * @return \Intranet\IntranetBundle\Entity\Client 
     */
    public function getClient()
    {
        return $this->client;
    }

    public function addProjectUser(\Intranet\IntranetBundle\Entity\ProjectUser $projectUser)
    {
        $this->projectUsers[] = $projectUser;
    }

    public function removeProjectUser(\Intranet\IntranetBundle\Entity\ProjectUser $projectUser)
    {
        $this->projectUsers->removeElement($projectUser);
    }

    public function getProjectUsers()
    {
        return $this->projectUsers;
    }
}

My ProjectUser.php

namespace Intranet\IntranetBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 */
class ProjectUser
{

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Project", inversedBy="projectUsers")
     */
    private $project;

    /**
     * @ORM\Id
     * @ORM\ManyToOne(targetEntity="Intranet\UserBundle\Entity\User")
     */
    private $user;

    /**
     * @ORM\Column(name="profil", type="smallint")
     */
    private $profil;

    public function setProject(\Intranet\IntranetBundle\Entity\Project $project)
    {
        $project->addProjectUser($this);
        $this->project = $project;
    }
    public function getProject()
    {
        return $this->project;
    }

    public function setUser(\Intranet\UserBundle\Entity\User $user)
    {
        $this->user = $user;
    }
    public function getUser()
    {
        return $this->user;
    }

    public function setProfil($profil)
    {
        $this->profil = $profil;
    }
    public function getProfil()
    {
        return $this->profil;
    }
}

profil = smallint for the job of the user (1=manager, 2=designer, ...)

My ProjectController (addAction)

public function addAction()
{
    $project = new Project;
    $form    = $this->createForm(new ProjectType, $project);
    $request = $this->get('request');

    if ($request->getMethod() == 'POST') {
        $form->bind($request);

        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($project);
            $em->flush();

            foreach ($form->get('projectUsers')->getData() as $u) {
                $u->setProject($project);
                $em->persist($u);
            }
            $em->flush();

            $this->get('session')->getFlashBag()->add('success', 'The project : '. $project->getName() .' has been added');
            return $this->redirect($this->generateUrl('clients_list'));
        }
    }
    return $this->render('IntranetIntranetBundle:Project:add_project.html.twig', array(
        'form' => $form->createView()
    ));
}

Thanks for your help

Hotgeart
  • 384
  • 10
  • 34
  • Why don't you add each user to the project? – A.L Jan 08 '14 at 11:51
  • Because i need the 'profil' field. Today i'm the designer of the project, but tomorrow i can be the manager for an other project. – Hotgeart Jan 08 '14 at 11:57
  • I was thinking of using `$project->addUser($user);` where `$user` is as instance of UserProject. – A.L Jan 08 '14 at 13:29
  • See http://stackoverflow.com/questions/15204349/manytomany-relationship-with-extra-fields-in-symfony2-orm-doctrine – A.L Jan 08 '14 at 13:34

2 Answers2

1

Well, first of all, you shouldn't specify @ORM\Id annotation on every foreign key in your ProjectUser entity - it is for primary keys.

Then you should declare column join on foreign key fields:

/**
* @ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\Project", inversedBy="projectUsers")
* @ORM\JoinColumn(name="project_id", referencedColumnName="id")
*/
private $project;

/**
* @ORM\ManyToOne(targetEntity="Intranet\IntranetBundle\Entity\User", inversedBy="projects")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;

You also should have a field like

class User
{
// ...

/**
 * @ORM\OneToMany(targetEntity="Intranet\IntranetBundle\Entity\ProjectUser", mappedBy="user")
 */
private $projects;

// ...
}

Finally, to add user to project, I suggest you embed a ProjectUserType form with user selection into ProjectType form. In your controller, you can have something like

public function addAction()
{
    $project = new Project;
    $projectUser = new ProjectUser();
    $projectUser->setProject($project);
    $project->addProjectUser($projectUser);
    $form = $this->createForm(new ProjectType, $project);
// ...

And in form ProjectUserType

class ProjectUserType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder->add('user', 'entity', array(
            'class' => 'Intranet:IntranetBundle:User'
        ));
// ...

Hope this helps at least a little bit.

reafle
  • 254
  • 1
  • 10
0

When you code : $em->persist($project);

$project is equal to $project = new Project; (don't you have forget '()' ?)

Actually the $projet is empty... To do this, I think you forget to code :

$project = $form->getData();
BENARD Patrick
  • 30,363
  • 16
  • 99
  • 105