why Symfony2 performs 40 DB queries if I use following code:
$em = $this->getDoctrine()->getManager();
$records = $em->getRepository('MyWebBundle:Highlight')->findAll();
I thought that findAll() method returns only all items from Highlight entity and associations to other entities replaces Proxy objects. But now findAll() method gettings all associations entities.
Do you know where is the problem ?
indexAction
public function indexAction() {
$em = $this->getDoctrine()->getManager();
$records = $em->getRepository('MyWebBundle:Highlight')->findAll();
$csrf = $this->get('security.csrf.token_manager');
$token = $csrf->refreshToken(self::FORM_TOKEN_ID);
$params = array(
"data" => array(
"all" => $records,
),
"token" => $token->getValue(),
"static" => array(
"add" => $this->generateUrl("admin_highlight_add"),
"edit" => $this->generateUrl("admin_highlight_edit"),
"del" => $this->generateUrl("admin_highlight_del"),
),
);
$ser = $this->get('jms_serializer');
$jsonContent = $ser->serialize($params, 'json');
return array('jsonContent' => $jsonContent);
}
Highlight entity
namespace My\WebBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
/**
* Highlight
*
* #JMS\ExclusionPolicy("none")
* #ORM\Table()
* #ORM\Entity(repositoryClass="My\WebBundle\Entity\HighlightRepository")
*/
class Highlight {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="abbreviation", type="string", length=8, unique=true)
*/
private $abbreviation;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=80, nullable=true)
*/
private $description;
/**
* #var string
*
* #ORM\Column(name="color", type="string", length=7)
*/
private $color;
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Goods", mappedBy="highlight")
*/
private $goods;
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Calibration", mappedBy="highlight")
*/
private $calibrations;
/**
* Constructor
*/
public function __construct() {
$this->goods = new \Doctrine\Common\Collections\ArrayCollection();
$this->calibrations = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set abbreviation
*
* #param string $abbreviation
* #return Highlight
*/
public function setAbbreviation($abbreviation) {
$this->abbreviation = $abbreviation;
return $this;
}
/**
* Get abbreviation
*
* #return string
*/
public function getAbbreviation() {
return $this->abbreviation;
}
/**
* Set description
*
* #param string $description
* #return Highlight
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription() {
return $this->description;
}
/**
* Set color
*
* #param string $color
* #return Highlight
*/
public function setColor($color) {
$this->color = $color;
return $this;
}
/**
* Get color
*
* #return string
*/
public function getColor() {
return $this->color;
}
/**
* Add goods
*
* #param \My\WebBundle\Entity\Goods $goods
* #return Highlight
*/
public function addGood(\My\WebBundle\Entity\Goods $goods) {
$this->goods[] = $goods;
return $this;
}
/**
* Remove goods
*
* #param \My\WebBundle\Entity\Goods $goods
*/
public function removeGood(\My\WebBundle\Entity\Goods $goods) {
$this->goods->removeElement($goods);
}
/**
* Get goods
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getGoods() {
return $this->goods;
}
/**
* Add calibrations
*
* #param \My\WebBundle\Entity\Calibration $calibrations
* #return Highlight
*/
public function addCalibration(\My\WebBundle\Entity\Calibration $calibrations) {
$this->calibrations[] = $calibrations;
return $this;
}
/**
* Remove calibrations
*
* #param \My\WebBundle\Entity\Calibration $calibrations
*/
public function removeCalibration(\My\WebBundle\Entity\Calibration $calibrations) {
$this->calibrations->removeElement($calibrations);
}
/**
* Get calibrations
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCalibrations() {
return $this->calibrations;
}
}
Highlight repository is empty
I think the problem comes from the serializer. Since you serializer highliths, each of them has their properties serialized as well which means that lazy query will be performed to retieved Goods which will be also serialized.
You should then prevent this behaviour by adding annotations to highlight's goods property as this
use ...
use JMS\SerializerBundle\Annotation\ExclusionPolicy;
use JMS\SerializerBundle\Annotation\Exclude;
/**
* ...
* #ExclusionPolicy("none")
*/
class Highlight
{
/**
* ...
* #Exclude
*/
private $goods;
}
You can have further details about exclusion stratigies from JMSSerializer doc
findAll itself does not perform many queries. Queries are executed when you access related entity via getters. As relation are not fetched eagerly, they first time are fetched when you are acessing them.
I think serializer access all children to send your object.
See Doctrine documentation
Whenever you have a managed entity instance at hand, you can traverse
and use any associations of that entity that are configured LAZY as if
they were in-memory already. Doctrine will automatically load the
associated objects on demand through the concept of lazy-loading.
To prevent this either disable children serialization or use fetch EAGER or build a DQL query, which prefetch all the children alongside with parents, like (just sample, not valid DQL)
SELECT Highlight, Good, Calibration
FROM Highlights Highlight
LEFT JOIN Highlight.googs Good
LEFT JOIN Goog.calibrations Calibration
WHERE ...
Related
There is a relationship between the rubric and brand table (Many rubric to One brand).
Here is my code
$dbChoices = $this->getConfigurationPool()
->getContainer()
->get('Doctrine')
->getManager()
->getRepository('RibambelMainBundle:RubricMenu')
->findBy(array('brand_id' => 2));
Everytime this part is run, I got the following error:
Unrecognized field: brand_id
The brand_id column is found in the rubric table.
Anyone who can help me with this or show me another way of doing it?
class RubricMenu
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Title", type="string", length=255)
*/
private $title;
/**
* #var int
*
* #ORM\Column(name="position", type="integer")
*/
private $position;
/**
* #ORM\ManyToOne(targetEntity="Brand")
* #ORM\JoinColumn(name="brand_id", nullable=false)
*/
private $brand;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $title
*
* #return RubricMenu
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set position
*
* #param integer $position
*
* #return RubricMenu
*/
public function setPosition($position)
{
$this->position = $position;
return $this;
}
/**
* Get position
*
* #return int
*/
public function getPosition()
{
return $this->position;
}
/**
* Set brand
*
* #param \Ribambel\MainBundle\Entity\Brand $brand
*
* #return RubricMenu
*/
public function setBrand(\Ribambel\MainBundle\Entity\Brand $brand = null)
{
$this->brand = $brand;
return $this;
}
/**
* Get brand
*
* #return \Ribambel\MainBundle\Entity\Brand
*/
public function getBrand()
{
return $this->brand;
}
}
Searching by a foreign key simply does not make sense from an object point of view. brand_id is not a field of your RubricMenu entity, brand is.
If you have a Brand entity, then you can use findBy (or the magic method findByBrand) like this: (with $myBrand an instance of Brand)
$repository->findBy(['brand' => $myBrand]);
// OR
$repository->findByBrand($myBrand);
If you simply have the id of your target entity, you can use the IDENTITY DQL function but in that case you cannot use findBy directly as it expects a valid field name. Thus, you will need to add a method in your RubricMenu repository. Your method could look like this:
public function findByBrandId($brandId)
{
$qb = $this->createQueryBuilder('rm');
$qb->where('IDENTITY(rm.brand) = :brandId')
->setParameter('brandId', $brandId);
return $qb->getQuery()->getResult();
}
On a side note, as pointed out by #l.g.karolos's answer, doing
$repository->findBy(['brand' => $brandId]);
// OR
$repository->findByBrand($brandId);
will also work as the findBy method internals will be able to resolve that the given parameter is an ID of a Brand entity, thus it will produce the same query as if you had given the corresponding Brand instance.
Based on your entity you should do the following.
$dbChoices = $this->getConfigurationPool()
->getContainer()
->get('Doctrine')
->getManager()
->getRepository('RibambelMainBundle:RubricMenu')
->findBy(array('brand' => 2));
i thing you can do:
$dbChoices = $this->getConfigurationPool()
->getContainer()
->get('Doctrine')
->getManager()
->getRepository('RibambelMainBundle:RubricMenu')
->findBy(array('brand' => $brand));
if you have $brand object (...\Entity\Brand)
Example on https://www.wanadev.fr/56-comment-realiser-de-belles-requetes-sql-avec-doctrine/ :
$user = …;
$category = …;
$em = $this->container->get("doctrine.orm.default_entity_manager");
$entities = $em->getRepository(MyClass::class)->findBy([
"user" => $user,
"category" => $category,
]);
I have Four Entities:
Batch
BachGroup
BachGroupApplication
Application
Entity 1(Batch) has OneToMany Bidirectional relationship with Entity 2(BatchGroup).
Entity 2(BatchGroup) has OneToMany Bidirectional relationship with Entity 3(BachGroupApplication).
Entity 3(BachGroupApplication) has ManyToOne Bidirectional relationship with Entity 4(Application).
DETAIL ON ABOVE ENTITIES:
Each batch has it's groups which i'm storing in bachGroup entity with batch reference column in it, now each batchGroup can have multiple applications so i have created BatchGroupApplication entity which holds reference to batchGroup and Application.
TODO:
I want to be able to search applications by individual batch group which i'm not able to do i searched the web and stackoverflow but failed to get it working! i don't know if my mind has stopped somewhere! my entities are listed below please help:
Batch Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Batch
*
* #ORM\Table(name="batch")
* #ORM\Entity(repositoryClass="ModelBundle\Repository\BatchRepository")
*/
class Batch
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ..............
/**
* If a Batch is removed all it's associated Groups will be deleted as well..
*
* #ORM\OneToMany(targetEntity="BatchGroup", mappedBy="batch", cascade={"remove"})
**/
private $batchGroups;
public function __construct() {
$this->batchGroups = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ...............
/**
* Add batchGroups
*
* #param \ModelBundle\Entity\BatchGroup $batchGroups
* #return Batch
*/
public function addBatchGroup(\ModelBundle\Entity\BatchGroup $batchGroups)
{
$this->batchGroups[] = $batchGroups;
return $this;
}
/**
* Remove batchGroups
*
* #param \ModelBundle\Entity\BatchGroup $batchGroups
*/
public function removeBatchGroup(\ModelBundle\Entity\BatchGroup $batchGroups)
{
$this->batchGroups->removeElement($batchGroups);
}
/**
* Get batchGroups
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBatchGroups()
{
return $this->batchGroups;
}
}
BatchGroup Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* BatchGroup
*
* #ORM\Table(name="batch_group")
* #ORM\Entity()
*/
class BatchGroup
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=128)
*/
private $title;
/**
* #ORM\ManyToOne(targetEntity="Batch", inversedBy="batchGroups")
* #ORM\JoinColumn(name="batch_id", referencedColumnName="id")
**/
private $batch;
/**
* #ORM\OneToMany(targetEntity="BatchGroupApplication", mappedBy="batchGroup", cascade={"remove"})
**/
private $batchGroupApplications;
public function __construct() {
$this->batchGroupApplications = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ............
/**
* Set batch
*
* #param \ModelBundle\Entity\Batch $batch
* #return BatchGroup
*/
public function setBatch(\ModelBundle\Entity\Batch $batch = null)
{
$this->batch = $batch;
return $this;
}
/**
* Get batch
*
* #return \ModelBundle\Entity\Batch
*/
public function getBatch()
{
return $this->batch;
}
/**
* Add batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
* #return BatchGroup
*/
public function addBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications[] = $batchGroupApplications;
return $this;
}
/**
* Remove batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
*/
public function removeBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications->removeElement($batchGroupApplications);
}
/**
* Get batchGroupApplications
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBatchGroupApplications()
{
return $this->batchGroupApplications;
}
}
BatchGroupApplication Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* BatchGroupApplication
*
* Table generated through this entity class will hold all application and can be filtered through BatchGroup
*
* #ORM\Table(name="batch_group_application")
* #ORM\Entity()
*/
class BatchGroupApplication
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="BatchGroup", inversedBy="batchGroupApplications")
* #ORM\JoinColumn(name="batch_group_id", referencedColumnName="id")
**/
private $batchGroup;
/**
* #ORM\ManyToOne(targetEntity="Application", inversedBy="batchGroupApplications")
* #ORM\JoinColumn(name="application_id", referencedColumnName="id")
**/
private $application;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set batchGroup
*
* #param \ModelBundle\Entity\BatchGroup $batchGroup
* #return BatchGroupApplication
*/
public function setBatchGroup(\ModelBundle\Entity\BatchGroup $batchGroup = null)
{
$this->batchGroup = $batchGroup;
return $this;
}
/**
* Get batchGroup
*
* #return \ModelBundle\Entity\BatchGroup
*/
public function getBatchGroup()
{
return $this->batchGroup;
}
/**
* Set application
*
* #param \ModelBundle\Entity\Application $application
* #return BatchGroupApplication
*/
public function setApplication(\ModelBundle\Entity\Application $application = null)
{
$this->application = $application;
return $this;
}
/**
* Get application
*
* #return \ModelBundle\Entity\Application
*/
public function getApplication()
{
return $this->application;
}
}
Application Entity
<?php
namespace ModelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Application
*
* #ORM\Table(name="application")
* #ORM\Entity(repositoryClass="ModelBundle\Repository\ApplicationRepository")
*/
class Application
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ............
/**
* #ORM\OneToMany(targetEntity="BatchGroupApplication", mappedBy="application", cascade={"remove"})
**/
private $batchGroupApplications;
public function __construct()
{
$this->batchGroupApplications = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
// ............
/**
* Add batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
* #return Application
*/
public function addBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications[] = $batchGroupApplications;
return $this;
}
/**
* Remove batchGroupApplications
*
* #param \ModelBundle\Entity\BatchGroupApplication $batchGroupApplications
*/
public function removeBatchGroupApplication(\ModelBundle\Entity\BatchGroupApplication $batchGroupApplications)
{
$this->batchGroupApplications->removeElement($batchGroupApplications);
}
/**
* Get batchGroupApplications
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getBatchGroupApplications()
{
return $this->batchGroupApplications;
}
}
ApplicationRepository
Search function in this repository is being called from controller and from data is being sent to it via parameter that is in key value pair format, because form may have more properties so i'm checking if user is searching through batchGroup as well if yes it should combine the result from there as well.
namespace ModelBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* ApplicationRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ApplicationRepository extends EntityRepository
{
/**
* Search Applications
*
* data: search form data in key => value fashion
*
*
*/
public function search($data)
{
$em = $this->getEntityManager();
$applicationRepository = $em->getRepository('ModelBundle:Application');
$qb = $applicationRepository->createQueryBuilder('a');
foreach ($data as $field => $value) {
if($field=="batchGroupApplications"){
$qb->andWhere(":value_$field MEMBER OF a.batchGroupApplications")->setParameter("value_$field", $value);
}else{
$qb->andWhere("a.$field = :value_$field")->setParameter("value_$field", $value);
}
}
$query = $qb->getQuery();
$result = $query->getResult();
return $result;
}
}
Controller
Here i'm creating a search form with batchGroupApplications dropdown, where user will choose any batch group and submit the form, once submitted user should be able to see all applications which are in that group but i'm getting nothing!
namespace SISBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use ModelBundle\Entity\Batch;
use SISBundle\Form\BatchType;
use ModelBundle\Entity\Application;
use DefaultBundle\Form\ApplicationType;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use SISBundle\Form\SearchApplicationType;
use ModelBundle\Entity\Group;
use ModelBundle\Entity\BatchGroup;
/**
* Admission controller.
*
* #Route("/admission")
*/
class AdmissionController extends Controller
{
// ..............
/**
* List Applications for selected Batch
*
* #Route("/{batch}/applications")
*
* #Method({"GET", "POST"})
* #Template()
*/
public function applicationsAction(Request $request, Batch $batch)
{
$em = $this->getDoctrine()->getManager();
if( $batch != null ){
$applications = $batch->getApplications();
/*
* Search Applications
*
*/
$searchForm = $this->createForm(SearchApplicationType::class, null, array(
'action' => $this->generateUrl('sis_admission_applications', array('batch'=>$batch->getId())),
'method' => 'POST',
'attr' => array(
'novalidate' => 'novalidate',
'id' => 'sis_application_search_form',
),
));
// Manually Populating groups dropdown based on their availability for current loaded batch
$searchForm->add('batchGroupApplications', ChoiceType::class, array(
'choices' => $batch->getBatchGroups(),
'choices_as_values' => true,
'multiple'=>false,
'choice_label'=>'title',
'placeholder'=>' - Select Group..',
)
);
$searchForm->handleRequest($request);
if ($searchForm->isSubmitted()) {
// data is an array with "firstname", "middlename", and "lastname" keys etc
$data = $searchForm->getData();
$applications = $em->getRepository('ModelBundle:Application')->search($data);
}
/*********************************** end: Search Applications ***************************************/
return array(
'batch' => $batch,
'applications' => $applications,
'searchForm' => $searchForm->createView(),
);
}
}
}
Again, please suggest how can i search applications through batchGroup in andWhere fashion as search form may have some more fields which are available in application entity, for other fields it's working fine but this search by BatchGroup is somewhat tricky may be because of complicated associations etc.
Looking forward to solution..
I have two entities in my code: Session and SessionPicture.
There is a OneToOne relationship between Session and SessionPicture. SessionPicture is the mapping entity and Session is the inverse one.
Session has an attribute called "Slug", which is generated thanks to the StofDoctrineExtensionsBundle https://github.com/stof/StofDoctrineExtensionsBundle, and using the Gedmo\Sluggable annotation.
I have a form to create a Session (so a SessionType), and this SessionType embeds a SessionPictureType. The SessionPicture class contains a file attribute (UploadedFile class) and I have used LifecycleEvents (PostPersist/PostUpdate) to upload the file of the SessionPicture, and give it the "slug" property of the related Session when I save it.
My issue is that when I try to change another property of my SessionPicture (let's say "alt") and give it the value of the "slug" of the session , I cannot do it in the PostPersist Lifecycle and then save it to my database, because this event takes place after the onFlush, which is too late. I have to do it in the PrePersist Lifecyle. But then the "slug" of my session is not available yet, because it is generated during the onFlush by the extension.
So how can I get the slug of the related session in the prePersist lifecyle?
(PS: I have a found a solution, which is to persist the session in my controller, flush with the Manager, and then to persist again and redo a flush() but it is not very elegant).
Please find my code below:
/**
* Session
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="MyBundle\Entity\SessionRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Session
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #ORM\OneToOne(targetEntity="MyBundle\Entity\SessionPicture", cascade={"persist", "remove"}, mappedBy="session")
* #ORM\JoinColumn(name="session_picture_id", referencedColumnName="id", nullable=true)
*/
private $sessionPicture;
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set sessionPicture
*
* #param \MyBundle\Entity\SessionPicture $sessionPicture
*
* #return Session
*/
public function setSessionPicture(MyBundle\Entity\SessionPicture $sessionPicture = null)
{
$this->sessionPicture = $sessionPicture;
return $this;
}
/**
* Get sessionPicture
*
* #return \MyBundle\Session\SessionPicture
*/
public function getSessionPicture()
{
return $this->sessionPicture;
}
And my SessionPicture code:
/**
* #var string
*
* #ORM\Column(name="alt", type="string", length=255, nullable=true)
*/
private $alt;
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255, nullable=true)
*/
private $path;
/**
* #ORM\OneToOne(targetEntity="MyBundle\Entity\Session", inversedBy="sessionPicture")
*/
private $session;
public $file;
private $fileNameForRemove;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set extension
*
* #param string $extension
*
* #return SessionPicture
*/
public function setExtension($extension)
{
$this->extension = $extension;
return $this;
}
/**
* Get extension
*
* #return string
*/
public function getExtension()
{
return $this->extension;
}
/**
* Set alt
*
* #param string $alt
*
* #return SessionPicture
*/
public function setAlt($alt)
{
$this->alt = $alt;
return $this;
}
/**
* Get alt
*
* #return string
*/
public function getAlt()
{
return $this->alt;
}
/**
* Set path
*
* #param string $path
*
* #return SessionPicture
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* #return string
*/
public function getPath()
{
return $this->path;
}
/**
* Set session
*
* #param \MyBundle\Entity\Session $session
*
* #return SessionPicture
*/
public function setSession(\NyBundle\Entity\Session $session = null)
{
$this->session = $session;
return $this;
}
/**
* Get session
*
* #return \MyBundle\Entity\Session
*/
public function getSession()
{
return $this->session;
}
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUpload()
{
if($this->file === null)
return ;
$extension = $this->file->guessExtension();
$this->extension = (string)$extension;
My issue is below, I cannot get the slug before the flush of the session
$this->alt = $this->getSession()->getSlug();
}
/**
* #ORM\PostPersist()
* #ORM\PostUpdate()
*/
public function upload()
{
But here, I can get the slug because my session has already been flushed and the slug generated
$this->alt = $this->getSession()->getSlug();
$this->path = $this->alt.'.'.$this->extension;
if ($this->file === null)
return ;
$this->file->move($this->getUploadRootDir(), $this->path);
unset($this->file);
}
Finally, here is an extract my controller code:
$form->handlerequest($request);
$validator = $this->get('validator');
$errorList = $validator->validate($session);
if (count($errorList) == 0)
{
$em = $this->getDoctrine()->getManager();
$em->persist($session);
$em->flush();
$em->persist($session);
$em->flush();
As you can see, I had to persist the $session and to flush it once, so that the slug is generated at the flush. Then persist again so that the slug is now available for the "alt" property of the SessionPicture at the prePersist n2, and flush again to save the alt property. But it is not very clean.
Thanks for any hel or advice. Thanks.
I would like to save my users search on my website. Thaht's why i have a Class User and i would like to create Search Class.
I have done that :
class Search
{
public function __construct()
{
$this->searched_date = new \Datetime();
}
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue
*/
private $id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="test\UserBundle\Entity\User")
*/
private $user;
/**
* #ORM\Column(name="termsearch", type="string", length=255, nullable="true")
*/
private $termsearch;
/**
* #ORM\Column(name="goodtitle", type="string", length=255, nullable="true")
*/
private $goodtitle;
/**
* #ORM\Column(name="searched_date", type="datetime")
*/
private $searched_date;
/**
* Set termsearch
*
* #param text $termsearch
*/
public function setTermsearch($termsearch)
{
$this->termsearch = $termsearch;
}
/**
* Get termsearch
*
* #return text
*/
public function getTermsearch()
{
return $this->termsearch;
}
/**
* Set searched_date
*
* #param datetime $searchedDate
*/
public function setSearchedDate($searchedDate)
{
$this->searched_date = $searchedDate;
}
/**
* Get searched_date
*
* #return datetime
*/
public function getSearchedDate()
{
return $this->searched_date;
}
/**
* Set user
*
* #param test\UserBundle\Entity\User $user
*/
public function setUser(\test\UserBundle\Entity\User $user)
{
$this->user = $user;
}
/**
* Get user
*
* #return test\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set goodtitle
*
* #param text $goodtitle
*/
public function setGoodtitle($goodtitle)
{
$this->goodtitle = $goodtitle;
}
/**
* Get goodtitle
*
* #return text
*/
public function getGoodtitle()
{
return $this->goodtitle;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
And i would like to insert like that :
$em = $this->getDoctrine()->getEntityManager();
$user = $em->getRepository('TestUserBundle:User')->find($currentuser->getID());
$search = new Search();
$search->setUser($user);
$search->setTermsearch($termsearch);
$search->setGoodtitle($goodtitle);
$em->persist($search);
$em->flush();
Unfortunately i have this error :
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens (500 Internal Server Error)
And in the stack we can found that :
INSERT INTO s_search (user_id, termsearch, goodtitle, searched_date) VALUES (?, ?, ?, ?) ({"1":"c2c","2":"C2C Down The Road","3":{"date":"2012-10-31 00:18:47","timezone_type":3,"timezone":"Europe\/Paris"}})
I don't know how i can create this class Search...
Thank for for you help !
Remove #ORM\Id from the $user as #ManyToOne mapping reference does not require a type. See Doctrine's Annotation Reference for details. Doctrine takes care of the correct column type to hold the reference to another entity.
Make also sure that your User query really returns a valid $user. If it's possible that Search does not have $user, use #JoinColumn annotation to claim the column nullable. See another SO question Doctrine 2 can't use nullable=false in manyToOne relation?
I have a problem while json_encodeing a Entity.
public function jsonvoteAction($id) {
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('KorumAGBundle:AGVote')->findOneById($id);
$response = new Response(json_encode($entity, 200));
$response->headers->set('Content-Type',' application/json');
return $response;
}
This code returns me a the users entity
{"users":{"__isInitialized__":false,"id":null,"nickname":null,"pwd":null,"email":null,"firstname":null,"lastname":null,"poste":null,"addr1":null,"addr2":null,"pc":null,"country":null,"phone":null,"province":null,"acess":null,"site":null,"crew":null,"utilisateur":null}}
And when I var dymp my $entity, it returns both my AGVote and USers entity.
Here is my AGVote Entity
<?php
namespace Korum\AGBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Korum\AGBundle\Entity\AGVote
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class AGVote
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $question;
/**
* #ORM\Column(type="smallint")
*/
private $actif;
/**
* #ORM\ManyToOne(targetEntity="\Korum\KBundle\Entity\Users", cascade={"all"})
*/
public $users;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set question
* Nb : Only AG admin can set a question
* #param text $question
*/
public function setQuestion($question)
{
$this->question = $question;
}
/**
* Get question
*
* #return text
*/
public function getquestion()
{
return $this->question;
}
/**
* Set actif
*
* #param smallint $actif
*/
public function setActif($actif)
{
$this->actif = $actif;
}
/**
* Get actif
*
* #return smallint
*/
public function getActif()
{
return $this->actif;
}
/**
* Set Users
*
* #param Korum\KBundle\Entity\Province $Users
*/
public function setUsers(\Korum\KBundle\Entity\Users $users)
{
$this->users = $users;
}
/**
* Get Users
*
* #return Korum\KBundle\Entity\Users
*/
public function getUsers()
{
return $this->users;
}
}
Does anyone have an idea of what happened ?
I tried to install the JSMSerializerBundle but event with Metadata library at version 1.1.
When I want to clear my cache, it failed with error :
See :
JMSSerializerBundle Installation : Catchable Fatal Error: Argument 1 passed to JMSSerializerBundle\Twig\SerializerExtension::__construct()
By default, json_encode only uses public properties.
So it serialized the only public property of AGVote: $users. The content of $users was an instance of User; which public fields were serialized.
You could work around these by adding a toArray() method to your entities, and then doing json_encode($entity->toArray()), but i highly recommend you to have a look and use the JMSSerializedBundle.