pop_up
pop_up

Reputation: 1569

symfony2 persist manyToOne

i Have a single page application and i use symfony as a Rest API.

In my object "ResidenceIntervenant, i have a ManyToOne relation :

manyToOne:
    intervenant:
        targetEntity: Intervenant
        cascade: {  }
        fetch: LAZY
        mappedBy: null
        inversedBy: null
        joinColumns:
            intervenant_id:
                referencedColumnName: id
        orphanRemoval: false

When i do this :

$myData = json_decode($request->getContent(), true);
$intervenant = $this->em->getRepository('AppBundle:Intervenant')->find($intervenantId);
$relation = new ResidenceIntervenant();
$myData['intervenant'] = $intervenant->getId();
$form_relation = $this->formFactory->create(ResidenceIntervenantType::class, $relation, ['method' => "POST"]);
$form_relation->submit($myData, TRUE);
if ( ! $form_relation->isValid()) {
    $this->em->persist($relation);
    $this->em->flush();
}

it works and i have the id in my table

When i do :

$myData = json_decode($request->getContent(), true);
$intervenant = $this->em->getRepository('AppBundle:Intervenant')->find($intervenantId);
$relation = new ResidenceIntervenant();
$relation->setIntervenant($intervenant);
$form_relation = $this->formFactory->create(ResidenceIntervenantType::class, $relation, ['method' => "POST"]);
$form_relation->submit($myData, TRUE);
if ( ! $form_relation->isValid()) {
    $this->em->persist($relation);
    $this->em->flush();
}

it doesn't persists the id

Is this normal ?

my FormType biuldForm method :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('contratNum')
        ->add('appareilNum')
        ->add('intervenantOrigine')
        ->add('intervenant')
        ->add('residence');
}

Thanks for your help

EDIT : add informations to show my entities

I tried to add these linee but it neither works:

$intervenant->addResidenceIntervenant($relation);
$this->em->persist($intervenant);
$this->em->flush();

ResidenceIntervenant Entity :

<?php

namespace AppBundle\Entity;

/**
 * ResidenceIntervenant
 */
class ResidenceIntervenant
{
/**
 * @var integer
 */
private $id;

/**
 * @var string
 */
private $contratNum;

/**
 * @var string
 */
private $appareilNum;

/**
 * @var boolean
 */
private $intervenantOrigine;

/**
 * @var \AppBundle\Entity\Intervenant
 */
private $intervenant;

/**
 * @var \AppBundle\Entity\Residence
 */
private $residence;


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

/**
 * Set contratNum
 *
 * @param string $contratNum
 *
 * @return ResidenceIntervenant
 */
public function setContratNum($contratNum)
{
    $this->contratNum = $contratNum;

    return $this;
}

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

/**
 * Set appareilNum
 *
 * @param string $appareilNum
 *
 * @return ResidenceIntervenant
 */
public function setAppareilNum($appareilNum)
{
    $this->appareilNum = $appareilNum;

    return $this;
}

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

/**
 * Set intervenantOrigine
 *
 * @param boolean $intervenantOrigine
 *
 * @return ResidenceIntervenant
 */
public function setIntervenantOrigine($intervenantOrigine)
{
    $this->intervenantOrigine = $intervenantOrigine;

    return $this;
}

/**
 * Get intervenantOrigine
 *
 * @return boolean
 */
public function getIntervenantOrigine()
{
    return $this->intervenantOrigine;
}

/**
 * Set intervenant
 *
 * @param \AppBundle\Entity\Intervenant $intervenant
 *
 * @return ResidenceIntervenant
 */
public function setIntervenant(\AppBundle\Entity\Intervenant $intervenant = null)
{
    $this->intervenant = $intervenant;
    return $this;
}

/**
 * Get intervenant
 *
 * @return \AppBundle\Entity\Intervenant
 */
public function getIntervenant()
{
    return $this->intervenant;
}

/**
 * Set residence
 *
 * @param \AppBundle\Entity\Residence $residence
 *
 * @return ResidenceIntervenant
 */
public function setResidence(\AppBundle\Entity\Residence $residence = null)
{
    $this->residence = $residence;

    return $this;
}

/**
 * Get residence
 *
 * @return \AppBundle\Entity\Residence
 */
public function getResidence()
{
    return $this->residence;
}
}

ResidenceIntervenant.orm.yml

AppBundle\Entity\ResidenceIntervenant:
type: entity
table: residence_intervenant
indexes:
    fk_residence_intervenant_interv_id_idx:
        columns:
            - intervenant_id
    fk_residence_intervenant_res_id_idx:
        columns:
            - residence_id
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: false
        id: true
        generator:
            strategy: IDENTITY
fields:
    contratNum:
        type: string
        nullable: true
        length: 100
        options:
            fixed: false
        column: contrat_num
    appareilNum:
        type: string
        nullable: true
        length: 100
        options:
            fixed: false
        column: appareil_num
    intervenantOrigine:
        type: boolean
        nullable: false
        options:
            default: false
        column: intervenant_origine
manyToOne:
    intervenant:
        targetEntity: Intervenant
        cascade: ["persist"]
        fetch: LAZY
        mappedBy: null
        inversedBy: null
        joinColumns:
            intervenant_id:
                referencedColumnName: id
        orphanRemoval: false
    residence:
        targetEntity: Residence
        cascade: {  }
        fetch: LAZY
        mappedBy: null
        inversedBy: null
        joinColumns:
            residence_id:
                referencedColumnName: id
        orphanRemoval: false
lifecycleCallbacks: {  }

Intervenant Entity :

<?php

namespace AppBundle\Entity;

/**
 * Intervenant
 */
class Intervenant
{
/**
 * @var integer
 */
private $id;

/**
 * @var string
 */
private $libelleContact;

/**
 * @var string
 */
private $url;

/**
 * @var \AppBundle\Entity\Metier
 */
private $metier;

/**
 * @var \AppBundle\Entity\Tiers
 */
private $tiers;


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

/**
 * Set libelleContact
 *
 * @param string $libelleContact
 *
 * @return Intervenant
 */
public function setLibelleContact($libelleContact)
{
    $this->libelleContact = $libelleContact;

    return $this;
}

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

/**
 * Set url
 *
 * @param string $url
 *
 * @return Intervenant
 */
public function setUrl($url)
{
    $this->url = $url;

    return $this;
}

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

/**
 * Set metier
 *
 * @param \AppBundle\Entity\Metier $metier
 *
 * @return Intervenant
 */
public function setMetier(\AppBundle\Entity\Metier $metier = null)
{
    $this->metier = $metier;

    return $this;
}

/**
 * Get metier
 *
 * @return \AppBundle\Entity\Metier
 */
public function getMetier()
{
    return $this->metier;
}

/**
 * Set tiers
 *
 * @param \AppBundle\Entity\Tiers $tiers
 *
 * @return Intervenant
 */
public function setTiers(\AppBundle\Entity\Tiers $tiers = null)
{
    $this->tiers = $tiers;

    return $this;
}

/**
 * Get tiers
 *
 * @return \AppBundle\Entity\Tiers
 */
public function getTiers()
{
    return $this->tiers;
}
/**
 * @var \Doctrine\Common\Collections\Collection
 */
private $residenceIntervenant;

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

/**
 * Add residenceIntervenant
 *
 * @param \AppBundle\Entity\ResidenceIntervenant $residenceIntervenant
 *
 * @return Intervenant
 */
public function addResidenceIntervenant(\AppBundle\Entity\ResidenceIntervenant $residenceIntervenant)
{
    $this->residenceIntervenant[] = $residenceIntervenant;

    return $this;
}

/**
 * Remove residenceIntervenant
 *
 * @param \AppBundle\Entity\ResidenceIntervenant $residenceIntervenant
 */
public function removeResidenceIntervenant(\AppBundle\Entity\ResidenceIntervenant $residenceIntervenant)
{
    $this->residenceIntervenant->removeElement($residenceIntervenant);
}

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

Intervenant.orm.yml :

AppBundle\Entity\Intervenant:
type: entity
table: intervenant
indexes:
    fk_intervenant_metier_id_idx:
        columns:
            - metier_id
    fk_intervenant_tiers_id_idx:
        columns:
            - tiers_id
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: false
        id: true
        generator:
            strategy: IDENTITY
fields:
    libelleContact:
        type: string
        nullable: false
        length: 255
        options:
            fixed: false
        column: libelle_contact
    url:
        type: string
        nullable: true
        length: 255
        options:
            fixed: false
oneToMany:
    residenceIntervenant:
        targetEntity: ResidenceIntervenant
        mappedBy: intervenant
        cascade: [remove]
oneToOne:
    tiers:
        targetEntity: Tiers
        joinColumn:
            name: tiers_id
            referencedColumnName: id
        cascade: [remove, persist]
manyToOne:
    metier:
        targetEntity: Metier
        cascade: ["persist"]
        fetch: LAZY
        mappedBy: null
        inversedBy: null
        joinColumns:
            metier_id:
                referencedColumnName: id
        orphanRemoval: false
lifecycleCallbacks: {  }

EDIT : Problem solved i updated addResidenceIntervenant like this :

public function addResidenceIntervenant(\AppBundle\Entity\ResidenceIntervenant $residenceIntervenant)
{
    $this->residenceIntervenant[] = $residenceIntervenant;
    $residenceIntervenant->setIntervenant($this);

    return $this;
}

i added these lines after persisting my relation :

$intervenant->addResidenceIntervenant($relation);
$this->em->persist($intervenant);

Upvotes: 0

Views: 801

Answers (1)

Aerendir
Aerendir

Reputation: 6379

Your second example has this line:

$relation->setIntervenant($intervenant);

Does the method setIntervenant() set the relation?

I think you should do something like this:

public function setIntervenant(Intervenant $intervenant)
{
    $this->intervenant = $intervenant;
    $intervenant->setResidence($this);
}

Anyway, the relations in Doctrine can be unidirectional or bidirectional.

Your Many-To-One relation seems to be unidirectional. You should set a One-To-Many relation on your Intervenant entity.

Read more about this in the Doctrine documentation:

So, you should trait your Intervenant as the Doctrine treats the Feature while your ResidenceIntervenant has to be treated as the Product in the Doctrine documentation.

Upvotes: 2

Related Questions