in symfony sonata :
I have an object CONTACT contains many ROLE -
i want to see all was inside an entity role in form mapper:
my entity role have 4 parameters.
(label function, phone, email, etc...)
actually i just have a link to the object.
(but i want to see all the parameters was inside the entity)
i try this in my form mapper of my class ADMIN
$showMapper
->with('CONTACT - FUNCTION')
->add('role')
->end()
namespace AdminBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Role
*/
class Role
{
/**
* #var int
*/
private $id;
/**
* #var string(unique=true)
*/
private $function;
/**
* #var int
*/
private $organisation;
/**
* #var string
*/
private $phone;
/**
* #var string
*/
private $email;
/**
* #var int
*/
private $contact=null;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
public function __toString(){
return sprintf("%s %s", $this->getFunction(), $this->getOrganisation());
}
public function getFunction_name()
{
return $this->getFunction();
}
/**
* Set contact
*
* #param int $contact
*
* #return role
*/
public function setContact($contact)
{
$this->contact = $contact;
return $this;
}
/**
* Get contact
*
* #return int
*/
public function getContact()
{
return $this->contact;
}
/**
* Set function
*
* #param string $function
*
* #return Role
*/
public function setFunction($function)
{
$this->function = $function;
return $this;
}
/**
* Get function
*
* #return string
*/
public function getFunction()
{
return $this->function;
}
/**
* Set organisation
*
* #param int $organisation
*
* #return Role
*/
public function setOrganisation($organisation)
{
$this->organisation = $organisation;
return $this;
}
/**
* Get organisation
*
* #return int
*/
public function getOrganisation()
{
return $this->organisation;
}
/**
* Set phone
*
* #param string $phone
*
* #return Role
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set email
*
* #param string $email
*
* #return Role
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
}
and my doctrine file
AdminBundle\Entity\Role:
type: entity
table: null
repositoryClass: AdminBundle\Repository\RoleRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
function:
type: string
length: 100
unique: true
phone:
type: string
length: 100
nullable: TRUE
email:
type: string
length: 100
nullable: TRUE
manyToOne:
organisation:
targetEntity: AdminBundle\Entity\Organisation
joinColumn:
name: organisation
referencedColumnName: id
nullable: TRUE
manyToMany:
contact:
targetEntity: AdminBundle\Entity\Contact
joinTable:
name: allrole
joinColumns:
role:
referencedColumnName: id
inverseJoinColumns:
contact:
referencedColumnName: id
Create a __toString() method into your Role entity with properties you want to display.
public function __toString()
{
return (string) "Function: " . $this->function . ", Phone: " . $this->phone . ", Email: " . $this->email;
}
Related
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);
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:
Many-to-One, Unidirectional (This is what you did)
One-to-Many, bidirectional (This is what you should do)
One-To-Many, Unidirectional with Join Table (Just for completeness)
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.
I have a problem related to Doctrine2:
1- I have two tables joining on a many-to-one relation:
Table 1 - Activity
The Schema:
Backend\adminBundle\Entity\Activity:
type: entity
table: activity
indexes:
result_id:
columns:
- result_id
id:
id:
type: integer
nullable: false
unsigned: false
comment: ''
id: true
generator:
strategy: IDENTITY
fields:
......
manyToOne:
result:
targetEntity: Actionresult
cascade: { }
mappedBy: null
inversedBy: null
joinColumns:
result_id:
referencedColumnName: id
orphanRemoval: false
The Entity
<?php
namespace Backend\adminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Activity {
/**
* #var \Backend\adminBundle\Entity\Actionresult
*
* #ORM\ManyToOne(targetEntity="Backend\adminBundle\Entity\Actionresult")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="result_id", referencedColumnName="id")
* })
*/
private $result;
/**
* #var \Backend\adminBundle\Entity\SfGuardUser
*
* #ORM\ManyToOne(targetEntity="Backend\adminBundle\Entity\SfGuardUser")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
/* There are other Properties */
/**
* Set result
*
* #param \Backend\adminBundle\Entity\Actionresult $result
* #return Activity
*/
public function setResult(\Backend\adminBundle\Entity\Actionresult $result = null)
{
$this->result = $result;
return $this;
}
/**
* Get result
*
* #return \Backend\adminBundle\Entity\Actionresult
*/
public function getResult()
{
return $this->result;
}
}
Table 2 - Actionresult Related to Activity Table by Id:
The schema:
Backend\adminBundle\Entity\Actionresult:
type: entity
table: actionresult
id:
id:
type: integer
nullable: false
unsigned: false
comment: ''
id: true
generator:
strategy: IDENTITY
fields:
name:
type: string
nullable: false
length: 255
fixed: false
comment: ''
lifecycleCallbacks: { }
The Entity:
<?php
namespace Backend\adminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Actionresult
*
* #ORM\Table(name="actionresult")
* #ORM\Entity
*/
class Actionresult
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Actionresult
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
The Question:
With doctrine i can refer from table Activity to Actionresult with the name result.
How can i refer with doctrine from table Actionresult to Activity??
Thank you in advance.
To be thorough, you should try and stick to one type of entity mapping in Symfony whenever possible. The #ORM* annotations are redundant if you use YAML config, and vice-versa. I'll provide the answer using YAML, and I believe you'll be able to convert to annotations if need be.
# Activity.yml
Activity:
type: entity
...
manyToOne:
result:
targetEntity: ActionResult
inversedBy: activities
# ActionResult.yml
Result:
type: entity
oneToMany:
activities:
targetEntity: Activity
mappedBy: result
# ActionResult.php
class Result {
protected $activities;
public function __construct()
{
$this->activities = new Doctrine\Common\Collections\ArrayCollection();
}
public function getActivities()
{
return $this->activities;
}
public function addActivity(Activity $activity)
{
$activity->setResult($this);
$this->activities->add($activity);
}
public function removeActivity(Activity $activity)
{
$activity->setResult(null);
$this->activities->removeElement($activity);
}
}
# Activity.php
class Activity {
protected $result;
public function getResult()
{
return $this->result;
}
public function setResult(ActionResult $result = null)
{
$this->result = $result;
}
}
Reference:
Bidirectional one to many: http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
As I am new to Symfony, I tried creating the entity relationship using Doctrine. I am getting the error Property "report" in "[bundle/entity/file_location" was already declared, but it must be declared only once" when I try to update the schema.
I have followed the Symfony documentation, but could not find the solution.
Entity/Report.php
<?php
namespace Aurora\ReportBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Report
*/
class Report
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $name;
/**
* #var string
*/
private $description;
/**
* var array
*/
private $reportFiles;
public function _construct() {
$this->reportFiles = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Report
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Report
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
}
Entity/ReportFile.php
<?php
namespace Aurora\ReportBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ReportFile
*/
class ReportFile
{
/**
* #var integer
*/
private $id;
/**
* #var Report
*/
private $report;
/**
* #var string
*/
private $name;
/**
* #var string
*/
private $path;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get report
*
* #return integer
*/
public function getReport()
{
return $this->report;
}
/**
* Set report
*
* #param integer $report
* #return ReportFile
*/
public function setReport($report)
{
$this->report = $report;
return $this;
}
/**
* Set name
*
* #param string $name
* #return ReportFile
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set path
*
* #param string $path
* #return ReportFile
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* #return string
*/
public function getPath()
{
return $this->path;
}
}
Doctrine/Report.orm
Aurora\ReportBundle\Entity\Report:
type: entity
table: null
repositoryClass: Aurora\ReportBundle\Entity\ReportRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
name:
type: string
length: 255
description:
type: text
lifecycleCallbacks: { }
oneToMany:
reportFiles:
targetEntity: ReportFile
mappedBy: report_id
Doctrine/ReportFile.orm.yml
Aurora\ReportBundle\Entity\ReportFile:
type: entity
table: null
repositoryClass: Aurora\ReportBundle\Entity\ReportFileRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
report:
type: integer
column: report_id
name:
type: string
length: 255
path:
type: string
length: 255
lifecycleCallbacks: { }
manyToOne:
report:
targetEntity: Report
inversedBy: reportFiles
joinColumn:
name: report_id
referencedColumnName: id
In Doctrine you shouldn't to declare relation columns as fields.
Remove report field from Doctrine/ReportFile.orm.yml but leave manyToOne relation. Doctrine will create column by itself.
I have a big problem with one of my entities in my Symfony project.
Some code first:
Address entity
<?php
namespace AppBundle\Entity;
class Address
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $street;
/**
* #var string|null
*/
private $postalCode;
/**
* #var string|null
*/
private $city;
/**
* #var string|null
*/
private $province;
/**
* #var float
*/
private $latitude;
/**
* #var float
*/
private $longtitude;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set street
*
* #param string $street
* #return Address
*/
public function setStreet($street)
{
$this->street = $street;
return $this;
}
/**
* Get street
*
* #return string
*/
public function getStreet()
{
return $this->street;
}
/**
* Set postalCode
*
* #param integer $postalCode
* #return Address
*/
public function setPostalCode($postalCode)
{
$this->postalCode = $postalCode;
return $this;
}
/**
* Get postalCode
*
* #return integer
*/
public function getPostalCode()
{
return $this->postalCode;
}
/**
* Set city
*
* #param string $city
* #return Address
*/
public function setCity($city)
{
$this->city = $city;
return $this;
}
/**
* Get city
*
* #return string
*/
public function getCity()
{
return $this->city;
}
/**
* Set province
*
* #param string $province
* #return Address
*/
public function setProvince($province)
{
$this->province = $province;
return $this;
}
/**
* Get province
*
* #return string
*/
public function getProvince()
{
return $this->province;
}
/**
* Set latitude
*
* #param string $latitude
* #return Address
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
return $this;
}
/**
* Get latitude
*
* #return string
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Set longtitude
*
* #param string $longtitude
* #return Address
*/
public function setLongtitude($longtitude)
{
$this->longtitude = $longtitude;
return $this;
}
/**
* Get longtitude
*
* #return string
*/
public function getLongtitude()
{
return $this->longtitude;
}
}
Address entity mapping:
AppBundle\Entity\Address:
type: entity
table: addresses
id:
id:
type: integer
generator:
strategy: AUTO
fields:
street:
type: string
nullable: false
postalCode:
name: postal_code
type: string
nullable: true
city:
type: string
nullable: false
province:
type: string
nullable: true
latitude:
type: decimal
scale: 12
precision: 18
nullable: true
longtitude:
type: decimal
scale: 12
precision: 18
nullable: true
Venue entity mapping:
AppBundle\Entity\Venue (shortened for the sake of example):
type: entity
table: venues
manyToOne:
address:
targetEntity: AppBundle\Entity\Address
joinColumn:
name: address_id
referencedColumnName: id
nullable: false
cascade: ["persist"]
The problem is that I face an exception being thrown:
Notice: Array to string conversion 500 Internal Server Error -
ContextErrorException
here $proxyCode = strtr($this->proxyClassTemplate, $venueholders); (in vendor/doctrine/common/lib/Doctrine/Common/Proxy/ProxyGenerator.php at line 280).
When I remove the relation, everything works correctly so it tells me there's some kind of issue with Address entity.
I've tried to clear the cache - no luck. Mapping looks ok to me, getters/setters are correct.
Any tips?
Did you try to reinstall your vendors completely? I see one issue in your question: $proxyCode = strtr($this->proxyClassTemplate, $venueholders);.
Line 280 of ProxyGenerator class should look like this: https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Proxy/ProxyGenerator.php#L280.
Did you try to apply search & replace on your code by any chance?
Try column: instead of name:
postalCode:
column: postal_code
type: string
nullable: true
I have two entities (Plan and PricingTier) that are set up to be mapped to each other. The PricingTier is set up to be a oneToMany and the Plan is set up to be a manyToOne. The mapped column is in the Plan entity; the plans database table has a pricing_tier_id column that links the two tables/entities together.
I have a form that creates a new plan. The form generates properly in the Twig file and when posted the $request->request->getAll(); returns an array of the posted values. In the array I can see that the pricingTierId has clearly been set to the id of the pricing tier I selected. When I peform the following:
$form->bind($request);
$newPlan = $form->getData();
$em = $this->getDoctrine()->getEntityManager();
$em->perist($newPlan);
$em->flush();
I get a thrown exception saying that pricing_tier_id can not be NULL. I have done a var_dump() to the $newPlan variable and it looks returns an object, including the object of the mapped pricing tier.
Can anyone suggest a solution to why I'd be getting this error? Relevant code and errors are below.
PlanController.php
namespace etrak\CustomerServiceBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use etrak\OnlineOrderProcessingBundle\Entity\Plan;
use etrak\OnlineOrderProcessingBundle\Entity\PricingTier;
use etrak\CustomerServiceBundle\Form\Type\PlanType;
use Symfony\Component\HttpFoundation\Request;
class PlanController extends Controller
{
public function indexAction($name)
{
return $this->render('etrakCustomerServiceBundle:Default:index.html.twig', array('name' => $name));
}
public function addPlanAction(Request $request)
{
// Set up a new Plan object
$plan = new Plan();
$form = $this->createForm(new PlanType(), $plan);
// Check to see if the form has been submitted
if ($request->isMethod('POST')) {
$form->bind($request);
var_dump($request->request->all()); die();
// Validate the form
if ($form->isValid()) {
$newPlan = $form->getData();
//var_dump($newPlan->getPricingTierId()); die();
$em = $this->getDoctrine()->getEntityManager();
$em->persist($newPlan);
$em->flush();
}
}
return $this->render('etrakCustomerServiceBundle:Plan:new.html.twig', array("form" => $form->createView()));
}
}
PlanType.php
namespace etrak\CustomerServiceBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class PlanType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'etrak\OnlineOrderProcessingBundle\Entity\Plan',
'cascade_validation' => true,
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$termsConditionsArray = array("1 Year Contract" => "1 Year Contract", "2 Year Contract" => "2 Year Contract");
$billingFrequencyArray = array("1" => "Monthly", "6" => "6 Months", "12" => "Yearly");
// Create the form
$builder->add('name', 'text', array('label' => 'Plan Name: ', 'required' => false));
$builder->add('description', 'text', array('label' => 'Plan Description: '));
$builder->add('termsConditions', 'choice', array('choices' => $termsConditionsArray, 'label' => 'Terms & Conditions'));
$builder->add('amount', 'text', array('label' => 'Plan Price: '));
$builder->add('affinity', 'choice', array('choices' => array('0' => 'Yes', '1' => 'No'), 'label' => 'Affinity? ', 'expanded' => true));
$builder->add('deactivationFee', 'text', array('label' => "Deactivation Fee: "));
$builder->add('recurringInMonths', 'choice', array('choices' => $billingFrequencyArray, 'label' => 'Billing Frequency: '));
$builder->add('pricingTierId', 'entity', array(
'class' => 'etrakOnlineOrderProcessingBundle:pricingTier',
'property' => 'name',
'label' => "Select Pricing Tier: "
));
$builder->add('activeStartDate', 'datetime', array('label' => "Effective Start Date: "));
$builder->add('activeEndDate', 'datetime', array('label' => "Effective End Date: "));
}
public function getName()
{
return 'plan';
}
}
Plan.php
namespace etrak\OnlineOrderProcessingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Plan
*/
class Plan
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $name;
/**
* #var string
*/
private $description;
/**
* #var string
*/
private $termsConditions;
/**
* #var boolean
*/
private $active;
/**
* #var decimal
*/
private $amount;
/**
* #var boolean
*/
private $affinity;
/**
* #var integer
*/
private $deactivationFee;
/**
* #var integer
*/
private $gracePeriodDays;
/**
* #var integer
*/
private $recurringInMonths;
/**
* #var integer
*/
private $pricingTierId;
/**
* #var date
*/
private $activeStartDate;
/**
* #var date
*/
private $activeEndDate;
/**
* #var \etrak\OnlineOrderProcessingBundle\Entity\PricingTier
*/
private $pricingTier;
/**
* Set pricingTier
*
* #param \etrak\OnlineOrderProcessingBundle\Entity\PricingTier $pricingTier
* #return Plan
*/
public function setPricingTier(\etrak\OnlineOrderProcessingBundle\Entity\PricingTier $pricingTier = null)
{
$this->pricingTier = $pricingTier;
return $this;
}
/**
* Get pricingTier
*
* #return \etrak\OnlineOrderProcessingBundle\Entity\PricingTier
*/
public function getPricingTier()
{
return $this->pricingTier;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Plan
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Plan
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set termsConditions
*
* #param string $termsConditions
* #return Plan
*/
public function setTermsConditions($termsConditions)
{
$this->termsConditions = $termsConditions;
return $this;
}
/**
* Get termsConditions
*
* #return string
*/
public function getTermsConditions()
{
return $this->termsConditions;
}
/**
* Set active
*
* #param boolean $active
* #return Plan
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/**
* Get active
*
* #return boolean
*/
public function getActive()
{
return $this->active;
}
/**
* Set amount
*
* #param decimal $amount
* #return Plan
*/
public function setAmount($amount)
{
$this->amount = $amount;
return $this;
}
/**
* Get amount
*
* #return decimal
*/
public function getAmount()
{
return $this->amount;
}
/**
* Set affinity
*
* #param boolean $affinity
* #return Plan
*/
public function setAffinity($affinity)
{
$this->affinity = $affinity;
return $this;
}
/**
* Get affinity
*
* #return boolean
*/
public function getAffinity()
{
return $this->affinity;
}
/**
* Set deactivationFee
*
* #param integer $deactivationFee
* #return Plan
*/
public function setDeactivationFee($deactivationFee)
{
$this->deactivationFee = $deactivationFee;
return $this;
}
/**
* Get deactivationFee
*
* #return integer
*/
public function getDeactivationFee()
{
return $this->deactivationFee;
}
/**
* Set gracePeriodDays
*
* #param integer $gracePeriodDays
* #return Plan
*/
public function setGracePeriodDays($gracePeriodDays)
{
$this->gracePeriodDays = $gracePeriodDays;
return $this;
}
/**
* Get gracePeriodDays
*
* #return integer
*/
public function getGracePeriodDays()
{
return $this->gracePeriodDays;
}
/**
* Set recurringInMonths
*
* #param integer $recurringInMonths
* #return Plan
*/
public function setRecurringInMonths($recurringInMonths)
{
$this->recurringInMonths = $recurringInMonths;
return $this;
}
/**
* Get recurringInMonths
*
* #return integer
*/
public function getRecurringInMonths()
{
return $this->recurringInMonths;
}
/**
* Set pricingTierId
*
* #param integer $pricingTierId
* #return Plan
*/
public function setPricingTierId($pricingTierId)
{
$this->pricingTierId = $pricingTierId;
return $this;
}
/**
* Get pricingTierId
*
* #return integer
*/
public function getPricingTierId()
{
return $this->pricingTierId;
}
/**
* Set activeStartDate
*
* #param \DateTime $activeStartDate
* #return Plan
*/
public function setActiveStartDate($activeStartDate)
{
$this->activeStartDate = $activeStartDate;
return $this;
}
/**
* Get activeStartDate
*
* #return \DateTime
*/
public function getActiveStartDate()
{
return $this->activeStartDate;
}
/**
* Set activeEndDate
*
* #param \DateTime $activeEndDate
* #return Plan
*/
public function setActiveEndDate($activeEndDate)
{
$this->activeEndDate = $activeEndDate;
return $this;
}
/**
* Get activeEndDate
*
* #return \DateTime
*/
public function getActiveEndDate()
{
return $this->activeEndDate;
}
/**
*
*/
public function prePersist()
{
if (!isset($this->affinity)) {
$this->setAffinity(0);
}
if (!isset($this->active)) {
$this->setActive(1);
}
}
}
Plan.orm.yml
#etrak/OnlineOrderProcessingBundle/Resources/config/doctrine/Entity/Plan.orm.yml
etrak\OnlineOrderProcessingBundle\Entity\Plan:
type: entity
table: plans
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
name:
type: string
length: 255
nullable: true
description:
type: text
nullable: true
termsConditions:
column: terms_conditions
type: text
nullable: true
active:
type: boolean
nullable: true
amount:
type: decimal
nullable: true
scale: 2
precision: 5
affinity:
type: boolean
nullable: true
deactivationFee:
column: deactivation_fee
type: decimal
scale: 2
precision: 5
nullable: true
gracePeriodDays:
column: grace_period_days
type: integer
nullable: true
recurringInMonths:
column: recurring_in_months
type: integer
nullable: true
pricingTierId:
column: pricing_tier_id
type: integer
activeStartDate:
column: active_start_date
type: date
activeEndDate:
column: active_end_date
type: date
lifecycleCallbacks:
prePersist: [ prePersist ]
manyToOne:
pricingTier:
targetEntity: PricingTier
inversedBy: plans
joinColumn:
name: pricing_tier_id
referencedColumnName: id
PricingTier.php
namespace etrak\OnlineOrderProcessingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* PricingTier
*/
class PricingTier
{
/**
* #var integer
*/
private $id;
/**
* #var integer
*/
private $productId;
/**
* #var string
*/
private $name;
/**
* #var string
*/
private $description;
/**
* #var integer
*/
private $minimumDevices;
/**
* #var boolean
*/
private $isAffinity;
/**
* #var string
*/
private $keyname;
/**
* #var string
*/
private $createdBy;
/**
* #var datetime
*/
private $createdOn;
/**
* #var datetime
*/
private $updatedOn;
/**
* Set productId
*
* #param integer $productId
* #return PricingTier
*/
public function setProductId($productId)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return integer
*/
public function getProductId()
{
return $this->productId;
}
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $plans;
/**
* Constructor
*/
public function __construct()
{
$this->plans = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add plans
*
* #param \etrak\OnlineOrderProcessingBundle\Entity\Plan $plans
* #return PricingTier
*/
public function addPlan(\etrak\OnlineOrderProcessingBundle\Entity\Plan $plans)
{
$this->plans[] = $plans;
return $this;
}
/**
* Remove plans
*
* #param \etrak\OnlineOrderProcessingBundle\Entity\Plan $plans
*/
public function removePlan(\etrak\OnlineOrderProcessingBundle\Entity\Plan $plans)
{
$this->plans->removeElement($plans);
}
/**
* Get plans
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPlans()
{
return $this->plans;
}
/**
* Set name
*
* #param string $name
* #return PricingTier
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return PricingTier
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set minimumDevices
*
* #param integer $minimumDevices
* #return PricingTier
*/
public function setMinimumDevices($minimumDevices)
{
$this->minimumDevices = $minimumDevices;
return $this;
}
/**
* Get minimumDevices
*
* #return integer
*/
public function getMinimumDevices()
{
return $this->minimumDevices;
}
/**
* Set isAffinity
*
* #param boolean $isAffinity
* #return PricingTier
*/
public function setIsAffinity($isAffinity)
{
$this->isAffinity = $isAffinity;
return $this;
}
/**
* Get isAffinity
*
* #return boolean
*/
public function getIsAffinity()
{
return $this->isAffinity;
}
/**
* Set keyname
*
* #param string $keyname
* #return PricingTier
*/
public function setKeyname($keyname)
{
$this->keyname = $keyname;
return $this;
}
/**
* Get keyname
*
* #return string
*/
public function getKeyname()
{
return $this->keyname;
}
/**
* Set createdBy
*
* #param string $createdBy
* #return PricingTier
*/
public function setCreatedBy($createdBy)
{
$this->createdBy = $createdBy;
return $this;
}
/**
* Get createdBy
*
* #return string
*/
public function getCreatedBy()
{
return $this->createdBy;
}
/**
* Set createdOn
*
* #param \DateTime $createdOn
* #return PricingTier
*/
public function setCreatedOn($createdOn)
{
$this->createdOn = $createdOn;
return $this;
}
/**
* Get createdOn
*
* #return \DateTime
*/
public function getCreatedOn()
{
return $this->createdOn;
}
/**
* Set updatedOn
*
* #param \DateTime $updatedOn
* #return PricingTier
*/
public function setUpdatedOn($updatedOn)
{
$this->updatedOn = $updatedOn;
return $this;
}
/**
* Get updatedOn
*
* #return \DateTime
*/
public function getUpdatedOn()
{
return $this->updatedOn;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #ORM\PrePersist
*/
public function onPrePersist()
{
if (!isset($this->isAffinity)) {
$this->setIsAffinity(0);
}
$this->setCreatedOn(new \DateTime());
}
/**
* #ORM\PreUpdate
*/
public function onPreUpdate()
{
$this->setUpdatedOn(new \DateTime());
}
}
PricingTier.orm.yml
#etrak/OnlineOrderProcessingBundle/Resources/config/doctrine/Entity/PricingTier.orm.yml
etrak\OnlineOrderProcessingBundle\Entity\PricingTier:
type: entity
table: pricing_tiers
id:
id:
type: integer
generator: { strategy: AUTO }
fields:
productId:
column: product_id
type: integer
name:
type: string
length: 50
description:
type: string
length: 100
nullable: true
minimumDevices:
column: minimum_devices
type: integer
isAffinity:
column: is_affinity
type: boolean
keyname:
type: string
length: 55
createdBy:
column: created_by
type: string
length: 20
createdOn:
column: created_on
type: datetime
updatedOn:
column: updated_on
type: datetime
nullable: true
lifecycleCallbacks:
prePersist: [ onPrePersist ]
preUpdate: [ onPreUpdate ]
oneToMany:
plans:
targetEntity: Plan
mappedBy: pricingTier
That should be all of the files that relate to this. I didn't include the Twig file because it is simply one line that renders the form that is generated by the createView() magic method in the PlanController.
Thanks in advanced!
In your Plan.orm.yml:
pricingTierId:
column: pricing_tier_id
type: integer
which is the same column name as your many-to-one join. This is probably a bad practice. This is not set to nullable: true, and is probably the source of your problem. Explicitly, you don't need this field. Also in your form, you are loading the entity class for the pricingTierId, which is not an entity, and I think symfony is quite confused by this.
$builder->add('pricingTierId', 'entity', array( // add pricingTier
'class' => 'etrakOnlineOrderProcessingBundle:pricingTier', // not pricingTierId
'property' => 'name',
'label' => "Select Pricing Tier: "
));
I expect if you delete the offending yaml portion and adjust the form type your problem will go away.