Symfony 4 - Entity nulled on database registration - symfony

I'm a Symfony beginner and been stuck on this issue for a while. I have two entities (Mairie and Ville) with a many-to-one relation. Ville is an imported table, pre-filled with info. In a form, the user creates an instance of Mairie and with the form data, it will find a Ville to bind to.
Problem is : doctrine does find a Ville object when the Mairie is created, but when I want to set it to the Mairie object, it is nulled. Here's my code, in the Controller :
if($formMairie->isSubmitted() && $formMairie->isValid())
{
$repoMairie = $this->getDoctrine()->getRepository(Mairie::class);
$repoVilles = $this->getDoctrine()->getRepository(Villes::class);
$inseeInput = $mairie->getInsee();
$ville = $repoVilles->findOneBy(array("ville_code_commune" => $inseeInput));
dump($ville);
This dump works : it finds the right instance of Ville in the database and returns an object filled with the right properties.
$mairie->setVilles($ville);
This doesn't work, the Ville property of Mairie is set to null and I get no errors when I flush.
$mairieVille = $mairie->getVilles();
dump($mairieVille);
Returns null.
Why isn't the object registered ? I thought this could be an SQL issue since I've imported the Ville table but I can't find anything. I have used this method to bind other entities together and I've had no issue until now... Here are my two entities for more info (getters and setters not included) :
Ville:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Villes
*
* #ORM\Table(name="villes")
* #ORM\Entity
*/
class Villes
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="ville_id", type="integer", nullable=false)
*/
private $ville_id;
/**
* #var string|null
*
* #ORM\Column(name="ville_departement", type="string", length=3, nullable=true)
*/
private $ville_departement;
/**
* #var string|null
*
* #ORM\Column(name="ville_slug", type="string", length=255, nullable=true)
*/
private $ville_slug;
/**
* #var string|null
*
* #ORM\Column(name="ville_nom", type="string", length=45, nullable=true)
*/
private $ville_nom;
/**
* #var string|null
*
* #ORM\Column(name="ville_nom_simple", type="string", length=45, nullable=true)
*/
private $ville_nom_simple;
/**
* #var string|null
*
* #ORM\Column(name="ville_nom_reel", type="string", length=45, nullable=true)
*/
private $ville_nom_reel;
/**
* #var string|null
*
* #ORM\Column(name="ville_nom_soundex", type="string", length=20, nullable=true)
*/
private $ville_nom_soundex;
/**
* #var string|null
*
* #ORM\Column(name="ville_nom_methaphone", type="string", length=22, nullable=true)
*/
private $ville_nom_methaphone;
/**
* #var string|null
*
* #ORM\Column(name="ville_code_postal", type="string", length=255, nullable=true)
*/
private $ville_code_postal;
/**
* #var string|null
*
* #ORM\Column(name="ville_commune", type="string", length=3, nullable=true)
*/
private $ville_commune;
/**
* #var string
*
* #ORM\Column(name="ville_code_commune", type="string", length=5, nullable=false)
*/
private $ville_code_commune;
/**
* #var int|null
*
* #ORM\Column(name="ville_arrondissement", type="integer", nullable=true)
*/
private $ville_arrondissement;
/**
* #var string|null
*
* #ORM\Column(name="ville_canton", type="string", length=4, nullable=true)
*/
private $ville_canton;
/**
* #var int|null
*
* #ORM\Column(name="ville_amdi", type="integer", nullable=true)
*/
private $ville_amdi;
/**
* #var int|null
*
* #ORM\Column(name="ville_population_2010", type="integer", nullable=true)
*/
private $ville_population_2010;
/**
* #var int|null
*
* #ORM\Column(name="ville_population_1999", type="integer", nullable=true)
*/
private $ville_population_1999;
/**
* #var int|null
*
* #ORM\Column(name="ville_population_2012", type="integer", nullable=true)
*/
private $ville_population_2012;
/**
* #var int|null
*
* #ORM\Column(name="ville_densite_2010", type="integer", nullable=true)
*/
private $ville_densite_2010;
/**
* #var float|null
*
* #ORM\Column(name="ville_surface", type="float", precision=10, scale=0, nullable=true)
*/
private $ville_surface;
/**
* #var float|null
*
* #ORM\Column(name="ville_longitude_deg", type="float", precision=10, scale=0, nullable=true)
*/
private $ville_longitude_deg;
/**
* #var float|null
*
* #ORM\Column(name="ville_latitude_deg", type="float", precision=10, scale=0, nullable=true)
*/
private $ville_latitude_deg;
/**
* #var string|null
*
* #ORM\Column(name="ville_longitude_grd", type="string", length=9, nullable=true)
*/
private $ville_longitude_grd;
/**
* #var string|null
*
* #ORM\Column(name="ville_latitude_grd", type="string", length=8, nullable=true)
*/
private $ville_latitude_grd;
/**
* #var string|null
*
* #ORM\Column(name="ville_longitude_dms", type="string", length=9, nullable=true)
*/
private $ville_longitude_dms;
/**
* #var string|null
*
* #ORM\Column(name="ville_latitude_dms", type="string", length=8, nullable=true)
*/
private $ville_latitude_dms;
/**
* #var int|null
*
* #ORM\Column(name="ville_zmin", type="integer", nullable=true)
*/
private $ville_zmin;
/**
* #var int|null
*
* #ORM\Column(name="ville_zmax", type="integer", nullable=true)
*/
private $ville_zmax;
Mairie
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Mairie
*
* #ORM\Table(name="mairie", uniqueConstraints={#ORM\UniqueConstraint(name="UNIQ_3946A254A73F0036", columns={"ville_id"})}, indexes={#ORM\Index(name="IDX_3946A254CF94313", columns={"office_tourisme_id"})})
* #ORM\Entity
*/
class Mairie
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string|null
*
* #ORM\Column(name="mairie_nom_touristique", type="string", length=255, nullable=true)
*/
private $mairieNomTouristique;
/**
* #var string|null
*
* #ORM\Column(name="mairie_descriptif_1", type="string", length=255, nullable=true)
*/
private $mairieDescriptif1;
/**
* #var string|null
*
* #ORM\Column(name="mairie_descriptif_2", type="string", length=255, nullable=true)
*/
private $mairieDescriptif2;
/**
* #var string|null
*
* #ORM\Column(name="mairie_epci_rattachement", type="string", length=255, nullable=true)
*/
private $mairieEpciRattachement;
/**
* #var string
*
* #ORM\Column(name="mairie_maire_nom", type="string", length=255, nullable=false)
*/
private $mairieMaireNom;
/**
* #var string
*
* #ORM\Column(name="mairie_maire_prenom", type="string", length=255, nullable=false)
*/
private $mairieMairePrenom;
/**
* #var string|null
*
* #ORM\Column(name="mairie_adjoint_nom", type="string", length=255, nullable=true)
*/
private $mairieAdjointNom;
/**
* #var string|null
*
* #ORM\Column(name="mairie_adjoint_prenom", type="string", length=255, nullable=true)
*/
private $mairieAdjointPrenom;
/**
* #var string|null
*
* #ORM\Column(name="mairie_contact_nom", type="string", length=255, nullable=true)
*/
private $mairieContactNom;
/**
* #var string|null
*
* #ORM\Column(name="mairie_contact_prenom", type="string", length=255, nullable=true)
*/
private $mairieContactPrenom;
/**
* #var int
*
* #ORM\Column(name="mairie_telephone_contact", type="integer", nullable=false)
*/
private $mairieTelephoneContact;
/**
* #var string
*
* #ORM\Column(name="mairie_email_contact", type="string", length=255, nullable=false)
*/
private $mairieEmailContact;
/**
* #var string
*
* #ORM\Column(name="mairie_latitude", type="string", length=255, nullable=false)
*/
private $mairieLatitude;
/**
* #var string
*
* #ORM\Column(name="mairie_longitude", type="string", length=255, nullable=false)
*/
private $mairieLongitude;
/**
* #var string|null
*
* #ORM\Column(name="mairie_photo_1", type="string", length=255, nullable=true)
*/
private $mairiePhoto1;
/**
* #var string|null
*
* #ORM\Column(name="mairie_photo_2", type="string", length=255, nullable=true)
*/
private $mairiePhoto2;
/**
* #var string|null
*
* #ORM\Column(name="mairie_photo_3", type="string", length=255, nullable=true)
*/
private $mairiePhoto3;
/**
* #var string|null
*
* #ORM\Column(name="mairie_photo_4", type="string", length=255, nullable=true)
*/
private $mairiePhoto4;
/**
* #var string|null
*
* #ORM\Column(name="mairie_taxe_sejour_gestionnaire", type="string", length=255, nullable=true)
*/
private $mairieTaxeSejourGestionnaire;
/**
* #var string|null
*
* #ORM\Column(name="mairie_taxe_sejour_bareme", type="string", length=255, nullable=true)
*/
private $mairieTaxeSejourBareme;
/**
* #var string|null
*
* #ORM\Column(name="mairie_sejour_lien", type="string", length=255, nullable=true)
*/
private $mairieSejourLien;
/**
* #var string|null
*
* #ORM\Column(name="mairie_contact_nom_prenom", type="string", length=255, nullable=true)
*/
private $mairieContactNomPrenom;
/**
* #var string|null
*
* #ORM\Column(name="mairie_de_telephone", type="text", length=255, nullable=true)
*/
private $mairieDeTelephone;
/**
* #var string|null
*
* #ORM\Column(name="mairie_sejour_email", type="string", length=255, nullable=true)
*/
private $mairieSejourEmail;
/**
* #var string|null
*
* #ORM\Column(name="mairie_rappel_texte", type="string", length=255, nullable=true)
*/
private $mairieRappelTexte;
/**
* #var string|null
*
* #ORM\Column(name="mairie_rappel_lien", type="string", length=255, nullable=true)
*/
private $mairieRappelLien;
/**
* #var string|null
*
* #ORM\Column(name="mairie_logo", type="string", length=255, nullable=true)
*/
private $mairieLogo;
/**
* #var string|null
*
* #ORM\Column(name="mairie_logo_2", type="string", length=255, nullable=true)
*/
private $mairieLogo2;
/**
* #var \DateTime
*
* #ORM\Column(name="mairie_date_inscription", type="datetime", nullable=false)
*/
private $mairieDateInscription;
/**
* #var string|null
*
* #ORM\Column(name="mairie_tampon", type="string", length=255, nullable=true)
*/
private $mairieTampon;
/**
* #var string|null
*
* #ORM\Column(name="mairie_maire_signature", type="string", length=255, nullable=true)
*/
private $mairieMaireSignature;
/**
* #var string
*
* #ORM\Column(name="mairie_slug", type="string", length=255, nullable=false)
*/
private $mairieSlug;
/**
* #var string
*
* #ORM\Column(name="insee", type="string", length=255, nullable=false)
*/
private $insee;
/**
* #var string
*
* #ORM\Column(name="mairie_adresse", type="string", length=255, nullable=false)
*/
private $mairieAdresse;
/**
* #var string|null
*
* #ORM\Column(name="mairie_complement_adresse", type="string", length=255, nullable=true)
*/
private $mairieComplementAdresse;
/**
* #var string
*
* #ORM\Column(name="mairie_postal_code", type="string", length=10, nullable=false)
*/
private $mairiePostalCode;
/**
* #var string
*
* #ORM\Column(name="mairie_commune", type="string", length=255, nullable=false)
*/
private $mairieCommune;
/**
* #var \Villes
*
* #ORM\ManyToOne(targetEntity="Villes")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="ville_id", referencedColumnName="id")
* })
*/
private $ville;
/**
* #var \OfficeTourisme
*
* #ORM\ManyToOne(targetEntity="OfficeTourisme")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="office_tourisme_id", referencedColumnName="id")
* })
*/
private $officeTourisme;
public function __construct()
{
$this->user_id_heb = new ArrayCollection();
$this->hebergements = new ArrayCollection();
$this->mairie_id_user = new ArrayCollection();
$this->user = new ArrayCollection();
$this->hebergement = new ArrayCollection();
}
public function getVilles(): ?Villes
{
return $this->ville;
}
public function setVilles(?Villes $villes): self
{
$this->villes = $villes;
return $this;
}

In Mairie :
The function setVilles
public function setVilles(?Villes $villes): self
{
$this->villes = $villes;
return $this;
}
Should'nt it be :
$this->ville = $ville;
Because the property "Villes" with an S doesn't seem to exist.
So the function should be :
public function setVille(?Ville $ville): self
{
$this->ville = $ville;
return $this;
}

Your setVilles() function is seting $this->villes rather than $this->ville

Related

how to add a foreign key (one to many) in symfony

i have two entities 'Panier' and 'Reservation' i want to add a one to many foreign key (the Entity 'Panier' can have many 'Reservation' and 'Reservation' has only one 'Panier' id ) , so i have to add a foreign key 'id' of 'Panier' in my Reservation entity class .
this is my Reservation class :
class Reservation
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="dateReservation", type="datetime", nullable=false)
*/
private $datereservation = 'CURRENT_TIMESTAMP';
/**
* #var integer
*
* #ORM\Column(name="quantite", type="integer", nullable=false)
*/
private $quantite;
/**
* #var float
*
* #ORM\Column(name="total", type="float", precision=10, scale=0, nullable=true)
*/
private $total;
/**
* #var string
*
* #ORM\Column(name="type", type="string", length=255, nullable=false)
*/
private $type;
/**
* #var string
*
* #ORM\Column(name="seat", type="string", length=255, nullable=false)
*/
private $seat;
/**
* #var integer
*
* #ORM\Column(name="payer", type="integer", nullable=true)
*/
private $payer;
/**
* #var string
*
* #ORM\Column(name="nomReservation", type="string", length=255, nullable=true)
*/
private $nomreservation;
/**
* #var \Event
*
* #ORM\ManyToOne(targetEntity="Event")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="event_id", referencedColumnName="id")
* })
*/
private $event;
/**
* #var \User
*
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $user;
<?php
/** #Entity */
class Reservation {
/**
* #ManyToOne(targetEntity="Panier", inversedBy="reservations")
* #JoinColumn(name="panier_id", referencedColumnName="id")
*/
private $panier;
}
/** #Entity */
class Panier {
/**
* One Panier has many Reservations. This is the inverse side.
* #OneToMany(targetEntity="Reservation", mappedBy="panier")
*/
private $reservations;
public function __construct() {
$this->features = new ArrayCollection();
}
}

Doctrine: No identifier/primary key specified for

So I have everything set but I still get:
No identifier/primary key specified for Entity
"Bisna\Application\Entity\Company". Every Entity must have an
identifier/primary key.
Entity:
<?php
namespace Bisna\Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Company
*
* #ORM\Table(name="companies")
* #ORM\Entity
*/
class Company{
/**
* #var integer $id
*
* #ORM\Id
* ORM\Column(name="id", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string $industry
*
* #ORM\ManyToOne(targetEntity="CompanyIndustry", inversedBy="company_industry")
* #ORM\JoinColumn(name="industry_id", referencedColumnName="id", nullable=false)
*/
protected $industry;
/**
* #var string $billingAddress
*
* #ORM\ManyToOne(targetEntity="BillingAddress", inversedBy="billing_addresses")
* #ORM\JoinColumn(name="billing_address_id", referencedColumnName="id", nullable=false)
*/
protected $billingAddress;
/**
* #var string $companyName
*
* #ORM\Column(name="companyName", type="string", length=255, nullable=false)
*/
protected $companyName;
/**
* #var string $website
*
* #ORM\Column(name="website", type="string", length=255, nullable=true)
*/
protected $website;
/**
* #var string $address
*
* #ORM\Column(name="address", type="string", length=255, nullable=true)
*/
protected $address;
/**
* #var string $employeesNumber
*
* #ORM\Column(name="employees_number", type="string", length=255, nullable=true)
*/
protected $employeesNumber;
/**
* #var string $streetNumber
*
* #ORM\Column(name="street_number", type="string", length=255, nullable=true)
*/
protected $streetNumber;
/**
* #var string $street
*
* #ORM\Column(name="street", type="string", length=255, nullable=true)
*/
protected $street;
/**
* #var string $city
*
* #ORM\Column(name="city", type="string", length=255, nullable=false)
*/
protected $city;
/**
* #var string $cityVarname
*
* #ORM\Column(name="city_varname", type="string", length=255, nullable=true)
*/
protected $cityVarname;
/**
* #var string $state
*
* #ORM\Column(name="state", type="string", length=255, nullable=true)
*/
protected $state;
/**
* #var string $stateVarname
*
* #ORM\Column(name="state_varname", type="string", length=255, nullable=true)
*/
protected $stateVarname;
/**
* #var string $stateCode
*
* #ORM\Column(name="state_code", type="string", length=255, nullable=true)
*/
protected $stateCode;
/**
* #var string $postalCode
*
* #ORM\Column(name="postal_code", type="string", length=255, nullable=true)
*/
protected $postalCode;
/**
* #var string $country
*
* #ORM\Column(name="country", type="string", length=255, nullable=true)
*/
protected $country;
/**
* #var string $countryVarname
*
* #ORM\Column(name="country_varname", type="string", length=255, nullable=true)
*/
protected $countryVarname;
/**
* #var string $countryCode
*
* #ORM\Column(name="country_code", type="string", length=255, nullable=true)
*/
protected $countryCode;
/**
* #var string $latitude
*
* #ORM\Column(name="latitude", type="string", length=255, nullable=true)
*/
protected $latitude;
/**
* #var string $longitude
*
* #ORM\Column(name="longitude", type="string", length=255, nullable=true)
*/
protected $longitude;
/**
* #var string $email
*
* #ORM\Column(name="email", type="string", length=255, nullable=true)
*/
protected $email;
/**
* #var string $password
*
* #ORM\Column(name="password", type="string", length=255, nullable=true)
*/
protected $password;
/**
* #var string $firstname
*
* #ORM\Column(name="firstName", type="string", length=255, nullable=false)
*/
protected $firstname;
/**
* #var string $lastname
*
* #ORM\Column(name="lastName", type="string", length=255, nullable=false)
*/
protected $lastname;
/**
* #var Collection $jobs
*
* #ORM\OneToMany(targetEntity="CompanyJob", mappedBy="company", cascade={"persist", "remove"})
* #ORM\OrderBy({"created" = "ASC"})
*/
protected $jobs;
/**
* #var string $activationCode
*
* #ORM\Column(name="activationCode", type="string", length=255, nullable=true)
*/
protected $activationCode;
/**
* #var string $resetPasswordCode
*
* #ORM\Column(name="resetPasswordCode", type="string", length=255, nullable=true)
*/
protected $resetPasswordCode;
/**
* #var string $status ['activation', 'active', 'inactive']
*
* #ORM\Column(name="status", type="string", length=255, nullable=false)
*/
protected $status;
/**
* #var datetime $created
*
* #ORM\Column(name="created", type="datetime", nullable=false)
*/
protected $created;
/* .... */
}
I haven't made the tables yet, but still, I don't understand why I'm getting this error since I have everything. Any ideas?
Maybe it's because you missed a # before #ORM\Column annotation for $id property?
You should consider using Yaml doctrine mappings. It's a good way to separate entity from database columns definitions. And besides, your IDE should validate Yaml contents whereas it probably doesn't validate PHP comments as PHP code.

Symfony save date for every change status

how i can to do this: I have OrderWork entity this for order and have relation manyToMany with Status entity. All work good, but i want have date for every saved and updated order.
* Order
*
* #ORM\Table(name="order_work")
* #ORM\Entity(repositoryClass="AppBundle\Repository\OrderWorkRepository")
*/
class OrderWork
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Client", cascade={"persist"})
* #ORM\JoinColumn(name="client_id", referencedColumnName="id")
*/
private $client;
/**
* #var string
*
* #ORM\Column(name="orderNumber", type="string", length=255)
*/
private $orderNumber;
/**
* #var string
*
* #ORM\Column(name="orderCity", type="string", length=255)
*/
private $orderCity;
/**
* #var date
*
* #ORM\Column(name="date", type="string", length=255)
*/
private $date;
/**
* #var \DateTime
*
* #ORM\Column(name="orderDate", type="string", length=255, options={"default": NULL})
*/
private $orderDate;
/**
* #var \DateTime
*
* #ORM\Column(name="returnDate", type="string", length=255, nullable=true)
*/
private $returnDate;
/**
* #var string
*
* #ORM\Column(name="device", type="string", length=255)
*/
private $device;
/**
* #ORM\ManyToOne(targetEntity="SurrogatePhone", cascade={"persist"})
* #ORM\JoinColumn(name="surrogate_id", referencedColumnName="id")
*/
private $surrogatePhone;
/**
* #var int
*
* #ORM\Column(name="orderType", type="integer")
*/
public $orderType;
/**
* #ORM\ManyToMany(targetEntity="Status")
* #ORM\JoinTable(name="order_status",
* joinColumns={#ORM\JoinColumn(name="order_id", referencedColumnName="id", unique=false)},
* inverseJoinColumns={#ORM\JoinColumn(name="status_id", referencedColumnName="id", unique=false)}
* )
*/
private $status;
How better resolve this solution?
Define date in your constructor (for creating):
class OrderWork
{
//...
public function __construct()
{
$this->date = new DateTime();
}
}
And update date field when updating:
$orderWork->setDate(new DateTime());
$em->flush();

Symfony 20 Minute Page Load Times

Does anyone have a clue why in the world I would be getting 20 minute page load times in dev in Symfony2? It just randomly happens to me. One day I will get fast load times, the next day I am twiddling my thumbs waiting for a page to load. What can I check/disable/enable/etc? Thanks!
Here is my latest page load:
Time: 298068 ms
Here is the Entity for PurchaseOrder
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="archived_po_number", type="string", length=50, nullable=true)
* #Common\Versioned
*/
private $archived_po_number;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=50, nullable=true)
* #Common\Versioned
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="show_locations", type="string", length=1, nullable=true)
* #Common\Versioned
*/
private $show_locations;
/**
* #var integer
*
* #ORM\Column(name="freight", type="decimal", precision=10, scale=2, nullable=true)
* #Common\Versioned
*/
private $freight;
/**
* #var integer
*
* #ORM\Column(name="pallets", type="integer", nullable=true)
* #Common\Versioned
*/
private $pallets;
/**
* #var integer
*
* #ORM\Column(name="boxes", type="integer", nullable=true)
* #Common\Versioned
*/
private $boxes;
/**
* #var text
* #ORM\Column(name="internal_notes", type="text", nullable=true)
* #Common\Versioned
*/
private $internal_notes;
/**
* #var text
* #ORM\Column(name="sales_rep_notes", type="text", nullable=true)
* #Common\Versioned
*/
private $sales_rep_notes;
/**
* #var string
*
* #ORM\Column(name="custom_purchase_order_number", type="string", length=255, nullable=true)
* #Common\Versioned
*/
private $custom_purchase_order_number;
/**
* #ORM\ManyToOne(targetEntity="WIC\CommonBundle\Entity\CustomOptions", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="purchase_order_class", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $purchase_order_class;
/**
* #ORM\ManyToOne(targetEntity="WIC\WarehouseBundle\Entity\Warehouse", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="generated_by_location", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $generated_by_location;
/**
* #ORM\ManyToOne(targetEntity="WIC\InventoryLocationBundle\Entity\InventoryLocation", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="receive_location", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $receive_location;
/**
* #ORM\ManyToOne(targetEntity="WIC\WarehouseBundle\Entity\Warehouse", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="company_name", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $company_name;
/**
* #ORM\ManyToOne(targetEntity="WIC\WarehouseBundle\Entity\Warehouse", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="ship_to", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $ship_to;
/**
* #ORM\ManyToOne(targetEntity="WIC\WarehouseBundle\Entity\Warehouse", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="bill_to", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $bill_to;
/**
* #ORM\ManyToOne(targetEntity="WIC\CommonBundle\Entity\CustomOptions", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="payment_terms", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $payment_terms;
/**
* #ORM\ManyToOne(targetEntity="WIC\CommonBundle\Entity\CustomOptions", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="fob", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $fob;
/**
* #ORM\ManyToOne(targetEntity="WIC\CommonBundle\Entity\CustomOptions", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="ship_via", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $ship_via;
/**
* #var datetime
*
* #ORM\Column(name="ship_by", type="datetime", nullable=true)
* #Common\Versioned
*/
private $ship_by;
/**
* #var datetime
*
* #ORM\Column(name="cancel_by", type="datetime", nullable=true)
* #Common\Versioned
*/
private $cancel_by;
/**
* #var datetime
*
* #ORM\Column(name="due_by", type="datetime", nullable=true)
* #Common\Versioned
*/
private $due_by;
/**
* #var string
*
* #ORM\Column(name="nbt", type="string", length=2, nullable=true)
* #Common\Versioned
*/
private $nbt;
/**
* #ORM\OneToMany(targetEntity="WIC\PurchaseOrderLineItemBundle\Entity\PurchaseOrderLineItem", mappedBy="purchaseOrder", cascade={"remove"}, fetch="EAGER")
*/
protected $purchaseOrderLineItem;
/**
* #ORM\OneToMany(targetEntity="WIC\PurchaseOrderBundle\Entity\PurchaseOrderCharge", mappedBy="purchaseOrder", cascade={"remove"}, fetch="EAGER")
*/
protected $purchaseOrderCharge;
/**
* #ORM\OneToMany(targetEntity="WIC\PurchaseOrderBundle\Entity\PurchaseOrderPayment", mappedBy="purchaseOrder", cascade={"remove"}, fetch="EAGER")
*/
protected $purchaseOrderPayment;
/**
* #ORM\ManyToOne(targetEntity="WIC\SupplierBundle\Entity\Supplier", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="supplier_id", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
protected $supplier;
/**
* #ORM\ManyToOne(targetEntity="WIC\CommonBundle\Entity\CustomOptions", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="status_id", referencedColumnName="id", nullable=true)
* #Common\Versioned
*/
private $status;
/**
* #ORM\ManyToOne(targetEntity="WIC\UserBundle\Entity\User")
* #ORM\JoinColumn(name="created_by", referencedColumnName="id")
* #Common\Blameable(on="create")
*/
private $createdBy;
/**
* #ORM\ManyToOne(targetEntity="WIC\UserBundle\Entity\User")
* #ORM\JoinColumn(name="updated_by", referencedColumnName="id")
* #Common\Blameable(on="update")
*/
private $updatedBy;
/**
* #ORM\ManyToOne(targetEntity="WIC\AccountBundle\Entity\Account", inversedBy="purchaseOrders")
* #ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false)
* #Common\Versioned
* #Common\Blameable(on="create")
*/
protected $account;
/**
* #var datetime $created
*
* #Common\Timestampable(on="create")
* #ORM\Column(type="datetime")
*/
private $created;
/**
* #var datetime $updated
*
* #Common\Timestampable(on="update")
* #ORM\Column(type="datetime", nullable=true)
*/
private $updated;
/**
* #ORM\Column(name="deletedAt", type="datetime", nullable=true)
*/
private $deletedAt;
Here is my controller method listAction()
// verify access
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
$classIdentity = new ObjectIdentity('class', 'WIC\\PurchaseOrderBundle\\Entity\\PurchaseOrder');
if (false === $this->get('security.context')->isGranted('VIEW', $classIdentity)) {
throw new AccessDeniedException('Only an admin user has access to this section...');
}
}
// get user's account
$account = $this->getUser()->getAccount();
$search_form = $this->createForm(new PurchaseOrderSearchType());
$em = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$search_form->bind($request);
// if ($search_form->isValid()) {
$data = $search_form->getData();
$purchaseOrders = $em->getRepository('WICPurchaseOrderBundle:PurchaseOrder')->getListBy($data);
// }
} else {
if($this->get('request')->query->get('letter')){
}else{
}
// Set the up the pagination statement...
$em = $this->getDoctrine()->getManager();
$dql = "SELECT p FROM WIC\PurchaseOrderBundle\Entity\PurchaseOrder p WHERE p.account=:account_id ORDER BY p.created desc";
$query = $em->createQuery($dql);
$query->setParameters(array(
'account_id' => $account->getId(),
));
$paginator = $this->get('knp_paginator');
$paginatorObject = $paginator->paginate(
$query,
$this->get('request')->query->get('page', 1),25
);
// $purchaseOrders = $em->getRepository('WICPurchaseOrderBundle:PurchaseOrder')->findByAccount($account->getId(),array('id' => 'DESC'));
}
return array(
'heading' => 'Purchase Order',
'sidebarLeftTitle'=>'Purchase Order Menu',
'purchaseOrders' => $paginatorObject,
'search_form' => $search_form->createView(),
);
By default in app_dev.php you have the profiler bar, click on the timer and you will have a good start to debug (timeline with main/sub request, etc)
The issue was in the OneToMany relationship code where it says fetch="EAGER". This was pulling in all sorts of unnecessary associations and db queries. When I removed it, the db queries went down to 4 per page instead of 4000.
Are you using x-debug or any PHP level profiling? You've either got some form of recursion happening or one of the steps in the security\http\firewall process is taking a very long time to complete.
My suggestion would be
Look at your stack-trace and find anywhere there are highly repeated events around the security\http\firewall code and investigate if they exist
Quickly step through your code using x-debug, and find where the delay is occurring. With a few page reloads you should be able to step into the section which is causing the long page load times.
If you are using profiling, make sure your created files aren't ridiculously verbose. I've seen this long page load issue happen before due to profiling, where each page load would create a 20Gb+ profiling file.

Doctrine 2: fetch all records with or without match records in a one to many association in single table inheritance

I am trying to find the total count of listings in each categories base on listing location
What I am trying to do is if a user from United States visits the site only records from that location are shown. Also the category widget on the sidebar should take into account the total number of listing under each category in that location. If the visitor clicks on Chicago, The widget should recalculate to reflect the location 'Chicago'
with the code below
public function findCategoriesWithTotalListing($location)
{
$builder = $this->_em->createQueryBuilder();
$builder->select('c, count(l.id) AS num')
->from('Bundle\AdvertBundle\Entity\Category', 'c')
->leftJoin('c.listings','l')
->leftJoin('l.country','co')
->leftJoin('l.state','st')
->leftJoin('l.city','ci');
$builder->groupBy('c.id');
$result = $builder->getQuery()->getArrayResult();
print_r($result);
exit;
}
I am able to retrieve all categories with total count of each listing without the location param.
But if I introduce the location param, only those categories that have listings in that location are retrieved.
public function findCategoriesWithTotalListing($location)
{
$builder = $this->_em->createQueryBuilder();
$builder->select('c, count(l.id) AS num')
->from('Bundle\AdvertBundle\Entity\Category', 'c')
->leftJoin('c.listings','l')
->leftJoin('l.country','co')
->leftJoin('l.state','st')
->leftJoin('l.city','ci');
$orx = $builder->expr()->orX();
$orx->add($builder->expr()->like("co.slug", ':location'));
$orx->add($builder->expr()->like("st.slug", ':location'));
$orx->add($builder->expr()->like("ci.slug", ':location'));
$builder->andWhere($orx);
$builder->groupBy('c.id');
$builder->setParameter('location',$location);
$result = $builder->getQuery()->getArrayResult();
print_r($result);
exit;
}
I want all categories
What am I possibly doing wrong here
Thanks
Entities below
Category Entity
<?php
namespace Bundle\AdvertBundle\Entity;
use Bundle\FrameworkBundle\Entity\BaseEntity;
use Bundle\FrameworkBundle\Entity\DocumentInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* Category
*
* #ORM\Table(name="listings_categories")
* #ORM\Entity(repositoryClass="Bundle\AdvertBundle\Repository\CategoryRepository")
*/
class Category extends BaseEntity implements DocumentInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="slug", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="summary", type="text", precision=0, scale=0, nullable=false, unique=false)
*/
private $summary;
/**
* #var integer
*
* #ORM\Column(name="parent", type="integer", precision=0, scale=0, nullable=false, unique=false)
*/
private $parent;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\OneToMany(targetEntity="ListingItem", mappedBy="category")
*/
private $listings;
/**
* #var string
*
* #ORM\Column(name="thumbnail", type="string", length=255, precision=0, scale=0, nullable=true, unique=false)
*/
private $thumbnail;
/**
* #var string
*
* #ORM\Column(name="form_template", type="string", length=255, precision=0, scale=0, nullable=true, unique=false)
*/
private $formTemplate;
private $children;
private $totalChildren;
private $totaListing;
/* Getters and Setters*/
}
Listing Entity
<?php
namespace Bundle\AdvertBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Bundle\FrameworkBundle\Entity\DocumentInterface;
use Bundle\FrameworkBundle\Entity\BaseEntity;
/**
* #ORM\Entity (repositoryClass="Bundle\AdvertBundle\Repository\ListingItemRepository")
* #ORM\Table(name="listings")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="listing_type", type="string")
* #ORM\DiscriminatorMap({
"forsale" = "ForsaleItem",
"service" = "ServiceItem",
"job" = "JobItem",
"realestate" = "RealEstateItem",
"land" = "LandItem",
"house" = "HouseItem"
})
*/
abstract class ListingItem extends BaseEntity
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $title;
/**
* #var string
*
* #ORM\Column(name="slug", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $slug;
/**
* #var string
*
* #ORM\Column(name="price", type="decimal", precision=0, scale=2, nullable=false, unique=false)
*/
protected $price;
/**
* #var string
*
* #ORM\Column(name="description", type="text", precision=0, scale=0, nullable=false, unique=false)
*/
protected $description;
/**
* #var string
*
* #ORM\Column(name="thumbnail", type="string", length=255, precision=0, scale=0, nullable=true, unique=false)
*/
protected $thumbnail;
/**
* #var string
*
* #ORM\Column(name="status", type="string", length=100, precision=0, scale=0, nullable=false, unique=false)
*/
protected $status;
/**
* #var \DateTime
*
* #ORM\Column(name="date_created", type="datetime", precision=0, scale=0, nullable=true, unique=false)
*/
protected $dateCreated;
/**
* #var \DateTime
*
* #ORM\Column(name="date_approved", type="datetime", precision=0, scale=0, nullable=true, unique=false)
*/
protected $dateApproved;
/**
* #var \Bundle\AdvertBundle\Entity\Category
*
* #ORM\ManyToOne(targetEntity="Bundle\AdvertBundle\Entity\Category", inversedBy="listings")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=true)
* })
*/
protected $category;
/**
* #var \Bundle\UserBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="Bundle\UserBundle\Entity\User", inversedBy="listings")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
* })
*/
protected $user;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $name;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $email;
/**
* #var string
*
* #ORM\Column(name="contact_number", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $contactNumber;
/**
* #var \Bundle\LocationBundle\Entity\Country
*
* #ORM\ManyToOne(targetEntity="Bundle\LocationBundle\Entity\Country")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="country_id", referencedColumnName="id", nullable=true)
* })
*/
private $country;
/**
* #var \Bundle\LocationBundle\Entity\State
*
* #ORM\ManyToOne(targetEntity="Bundle\LocationBundle\Entity\State")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="state_id", referencedColumnName="id", nullable=true)
* })
*/
private $state;
/**
* #var \Bundle\LocationBundle\Entity\City
*
* #ORM\ManyToOne(targetEntity="Bundle\LocationBundle\Entity\City")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="city_id", referencedColumnName="id", nullable=true)
* })
*/
private $city;
protected $dateformat = 'd-M-Y';
}
Location Entity
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity (repositoryClass="Bundle\LocationBundle\Repository\LocationRepository")
* #ORM\Table(name="locations")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="location_type", type="string")
* #ORM\DiscriminatorMap({
"country" = "Country",
"state" = "State",
"city" = "City"
})
*/
abstract class Location
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $name;
/**
* #var string
*
* #ORM\Column(name="country_code", type="string", length=3, precision=0, scale=0, nullable=true, unique=false)
*/
protected $countryCode;
/**
* #var string
*
* #ORM\Column(name="slug", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $slug;
/**
* #var integer
*
* #ORM\Column(name="geoname_id", type="integer", precision=0, scale=0, nullable=false, unique=false)
*/
protected $geonameId;
/**
* #var string
*
* #ORM\Column(name="lng", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $lng;
/**
* #var string
*
* #ORM\Column(name="lat", type="string", length=255, precision=0, scale=0, nullable=false, unique=false)
*/
protected $lat;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\OneToMany(targetEntity="Bundle\LocationBundle\Entity\Location", mappedBy="parent")
*/
protected $children;
/**
* #var \Bundle\LocationBundle\Entity\Location
*
* #ORM\ManyToOne(targetEntity="Bundle\LocationBundle\Entity\Location", inversedBy="children")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", nullable=true)
* })
*/
protected $parent;
/**
* #var string
*
* #ORM\Column(name="currency_symbol", type="string", length=100, precision=0, scale=0, nullable=true, unique=false)
*/
protected $currencySymbol;
/* getters and setters*/
}
Country Entity
namespace Bundle\LocationBundle\Entity;
use Bundle\FrameworkBundle\Entity\DocumentInterface;
use Doctrine\ORM\Mapping as ORM;
/**
* Country
*
* #ORM\Table(name="locations")
* #ORM\Entity(repositoryClass="Bundle\LocationBundle\Repository\LocationRepository")
*/
class Country extends Location
{
/**
* Set countryCode
*
* #param string $countryCode
* #return Country
*/
public function setCountryCode($countryCode)
{
$this->countryCode = $countryCode;
return $this;
}
/**
* Get countryCode
*
* #return string
*/
public function getCountryCode()
{
return $this->countryCode;
}
}
State and city entites are just like the country
With your WHERE you are filtering out all those not matching categories so it can't count them. It should be possible to do by one query, but you have to move conditions from WHERE to get even not-matching rows and count them as 0.
Simple SQL version:
SELECT c.*, sum(IF(loc.code = 'x', 1, 0))
FROM category c
LEFT JOIN list l ON c.id = l.c_id
LEFT JOIN loc ON loc.id = l.loc_id
GROUP BY c.id
In Doctrine there is no IF, but you can use
CASE WHEN (<cond>) THEN 1 ELSE 0
as you use $orx expr.
Another posibility is moving conditions to those joins like in this example but then you have to do arbitrary join in doctrine to specify custom ON:
from documentation: Arbitrary JOIN Syntax (FROM User u JOIN Comment c WITH c.user = u.id)
then you will sum three counts for those three joined tables. It's doable but ugly.
Or subqueries as stated by #denys281 - select only from categories but select clause contains column which counts all matching listings for each category.
After several days of looking into subqueries in doctrine I finally got the code that works for my situation.
Here are some few pionts that got me to rethink about how I wrote the first code.
I needed all categories.
I needed a count of all listings in each category
Select only those listing that are related to the location parameter passed in.
Listings have a many to one associating with location.
The obvious solution is to use subquery as suggested by #danys281.
public function findCategoriesWithTotalListing($location)
{
$subQuery = $this->_em->createQueryBuilder();
$subQuery->select('COUNT(l.id)')
->from('Bundle\AdvertBundle\Entity\ListingItem','l')
->leftJoin('l.category','cat')
->leftJoin('l.country','co')
->leftJoin('l.state','st')
->leftJoin('l.city','ci')
->where('cat.id = c.id');
if($location instanceOf Country){
$subQuery->andWhere('co.slug = :location');
}
if($location instanceOf State){
$subQuery->andWhere('st.slug = :location');
}
if($location instanceOf City){
$subQuery->andWhere('ci.slug = :location');
}
$subQuery->andWhere("l.status = :status");
$builder = $this->_em->createQueryBuilder();
$builder->select("c, (".$subQuery->getDql().") AS num")
->from('Bundle\AdvertBundle\Entity\Category', 'c')
->setParameters(['location'=>$location->getSlug(),'status'=>'active'])
->groupBy('c');
return $builder->getQuery()->getResult();
}
Thank you all for given me the hint.

Resources