Remove row with FK as PK + Symfony2 and Doctrine - php

I have a table items with item_id, item_title, ... . I also have a table articles with a PK item_id that is a FK from the table items and a field article_body. I also have a many to many relationship from items to categories (item_has_catogories).
This is my Article Entity:
<?php
namespace Dxsolutions\DxsolutionsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Item
*
* #ORM\Table(name="articles")
* #ORM\Entity
*/
class Article extends Item
{
/**
* #var string
*
* #ORM\Column(name="article_body", type="text")
*/
protected $body;
/**
* Set body
*
* #param string $body
* #return Article
*/
public function setBody($body)
{
$this->body = $body;
return $this;
}
/**
* Get body
*
* #return string
*/
public function getBody()
{
return $this->body;
}
}
As you can see my Article Entity extends from the Item Entity, my Item Entity:
<?php
namespace Dxsolutions\DxsolutionsBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Item
*
* #ORM\Table(name="items")
* #ORM\Entity
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="item_type", type="string")
* #ORM\DiscriminatorMap({"ITEM"="Item", "ARTICLE"="Article"})
*/
class Item
{
/**
* #var integer
*
* #ORM\Column(name="item_id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="item_title", type="string", length=255)
*/
private $title;
/**
* #var \DateTime
*
* #ORM\Column(name="item_created", type="datetimetz")
*/
private $created;
/**
* #var \DateTime
*
* #ORM\Column(name="item_modified", type="datetimetz")
*/
private $updated;
/**
* #var \DateTime
*
* #ORM\Column(name="item_deleted", type="datetimetz")
*/
private $deleted;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Category", inversedBy="items")
* #ORM\JoinTable(name="items_has_categories",
* joinColumns={#ORM\JoinColumn(name="item_id", referencedColumnName="item_id")},
* inverseJoinColumns={#ORM\JoinColumn(name="category_id", referencedColumnName="category_id")}
* )
*/
protected $categories;
/**
* Constructor has to create Doctrine ArrayCollections
*/
public function __construct()
{
$this->categories = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
* #return Item
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set created
*
* #param \DateTime $created
* #return Item
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set updated
*
* #param \DateTime $updated
* #return Item
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* Get updated
*
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Set deleted
*
* #param \DateTime $deleted
* #return Item
*/
public function setDeleted($deleted)
{
$this->deleted = $deleted;
return $this;
}
/**
* Get deleted
*
* #return \DateTime
*/
public function getDeleted()
{
return $this->deleted;
}
/**
* Set category
*
* #param Category $category
*/
public function setCategories(Category $category)
{
$this->categories->add($category);
}
/**
* Get categories
*
* #return \Doctrine\Common\Collections\ArrayCollection
*/
public function getCategories()
{
return $this->categories;
}
}
Now I would like to delete an article (= an item).
This is what I do :
$em = $this->getDoctrine()->getManager();
$article = $em->getRepository('DxSolutionsBundle:Article')->find($id);
foreach($article->getCategories() as $c) {
$article->getCategories()->removeElement($c);
$em->flush();
}
$em->remove($article);
$em->flush();
But I always get this error:
An exception occurred while executing 'DELETE FROM items WHERE item_id = ?' with params [4]:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`dx-solutions`.`articles`, CONSTRAINT `fk_articles_items1` FOREIGN KEY (`item_id`) REFERENCES `items` (`item_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
What am I doing wrong?

The answer was as Hast said that I didn't defined 'CASCADE ON DELETE' at my FK item_id in my article table.

Related

Symfony Could not determine access type when using EntityType form builder

I have 2 entities Cars and Parts and I want to be able to create new Car with multiple parts. For this reason I made this form in CarsType
$builder->
add('make')->
add('model')->
add('travelledDistance')->
add('parts',EntityType::class,array(
'class' => Parts::class,
'choice_label'=>"name",
'query_builder' => function(PartsRepository $partsRepository){
return $partsRepository->getAllPartsForCarsForm();
},
'multiple' => true
));
It gives me this error
Could not determine access type for property "parts" in class
"AppBundle\Entity\Cars".
Here is my entity Cars
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Cars
*
* #ORM\Table(name="cars")
* #ORM\Entity(repositoryClass="AppBundle\Repository\CarsRepository")
*/
class Cars
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Make", type="string", length=255)
*/
private $make;
/**
* #var string
*
* #ORM\Column(name="Model", type="string", length=255)
*/
private $model;
/**
* #var int
*
* #ORM\Column(name="TravelledDistance", type="bigint")
*/
private $travelledDistance;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Parts", inversedBy="cars")
* #ORM\JoinTable(
* name="Parts_Cars",
* joinColumns={
* #ORM\JoinColumn(name="Part_Id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="Car_Id", referencedColumnName="id")
* })
*/
private $parts;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set make
*
* #param string $make
*
* #return Cars
*/
public function setMake($make)
{
$this->make = $make;
return $this;
}
/**
* Get make
*
* #return string
*/
public function getMake()
{
return $this->make;
}
/**
* Set model
*
* #param string $model
*
* #return Cars
*/
public function setModel($model)
{
$this->model = $model;
return $this;
}
/**
* Get model
*
* #return string
*/
public function getModel()
{
return $this->model;
}
/**
* Set travelledDistance
*
* #param integer $travelledDistance
*
* #return Cars
*/
public function setTravelledDistance($travelledDistance)
{
$this->travelledDistance = $travelledDistance;
return $this;
}
/**
* Get travelledDistance
*
* #return int
*/
public function getTravelledDistance()
{
return $this->travelledDistance;
}
/**
* #return mixed
*/
public function getParts()
{
return $this->parts;
}
}
And in case it matters here is my Parts entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Parts
*
* #ORM\Table(name="parts")
* #ORM\Entity(repositoryClass="AppBundle\Repository\PartsRepository")
*/
class Parts
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="Price", type="decimal", precision=10, scale=2)
*/
private $price;
/**
* #var int
*
* #ORM\Column(name="Quantity", type="integer")
*/
private $quantity;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Suppliers", inversedBy="parts")
* #ORM\JoinColumn(name="Supplier_Id", referencedColumnName="id")
*/
private $supplier;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Cars", mappedBy="parts")
*/
private $cars;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Parts
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* #param string $price
*
* #return Parts
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return string
*/
public function getPrice()
{
return $this->price;
}
/**
* Set quantity
*
* #param integer $quantity
*
* #return Parts
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* #return int
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* #return mixed
*/
public function getSupplier()
{
return $this->supplier;
}
/**
* #return mixed
*/
public function getCars()
{
return $this->cars;
}
public function __toString()
{
return $this->getName();
}
}
To save time here is the mapping between the 2 entities as well as the property parts in Cars
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Parts", inversedBy="cars")
* #ORM\JoinTable(
* name="Parts_Cars",
* joinColumns={
* #ORM\JoinColumn(name="Part_Id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="Car_Id", referencedColumnName="id")
* })
*/
private $parts;
and In Parts
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Cars", mappedBy="parts")
*/
private $cars;
Here is the newAction in CarsController
/**
* Creates a new car entity.
*
* #Route("/new", name="cars_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$carsRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Cars');
$car = new Cars();
$form = $this->createForm('AppBundle\Form\CarsType', $car);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($car);
$em->flush();
return $this->redirectToRoute('cars_show', array('id' => $car->getId()));
}
return $this->render('cars/new.html.twig', array(
'car' => $car,
'form' => $form->createView(),
));
}
My question is - How can I make it so that I can create new Car with several Parts and to save the relationship in the database so that when I retrieve the Car I can get the parts as well?
Basically how to make it so when I create a new car the relationship is saved in the parts_cars table which holds the id's?
Let Doctrine do the JOIN work
Since you're doing a ManyToMany (EntityToEntity), the #JoinColumn directives are not needed.
Try removing it from the Cars entity.
Cars
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Parts", inversedBy="cars")
*/
$parts
The only cases in which you need to specify the JoinColumns are:
Joining against self
Joining where the primary key is not the Entity ID.
Need to define fields in the join_table
Would be MUCH easier in this case to do A OneToMany J ManyToOne B
Since you're doing none of the above, Doctrine is having trouble accessing the Entities' IDENTITY fields for the join.

Error while putting element into DB with Doctrine2 Symfony

I'm trying to put into a table called question tag an element so:
//the question with Id 1 exist already
$question = new Question();
$question->setId(1);
//the tag with name PYTHON exist already
$tag = new Tag();
$tag->setName("PYTHON");
$questionTag = new QuestionTag();
$questionTag->setQuestion($question);
$questionTag->setTag($tag);
//now I call a service to put the item into DB
$questionTagPF = $this->get('facade.QuestionTagFacade');
$res = $questionTagPF->create($questionTag);
This is the method to save the entity:
public function create( $entity ) {
$this->entityManager->getConnection()->beginTransaction();
try {
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->entityManager->getConnection()->commit();
return true;
} catch ( Exception $e ) {
$this->entityManager->getConnection()->rollBack();
return false;
}
}
And these are the entity classes:
relation (between question and tag):
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* QuestionTag
*
* #ORM\Table(name="question_tag", indexes={#ORM\Index(name="question", columns={"question"}), #ORM\Index(name="index_question_tag", columns={"tag"})})
* #ORM\Entity
*/
class QuestionTag
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \AppBundle\Entity\Question
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Question", cascade={ "persist" })
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="question", referencedColumnName="id")
* })
*/
private $question;
/**
* #var \AppBundle\Entity\Tag
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Tag", cascade={ "persist" })
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="tag", referencedColumnName="name")
* })
*/
private $tag;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set question
*
* #param \AppBundle\Entity\Question $question
*
* #return QuestionTag
*/
public function setQuestion(\AppBundle\Entity\Question $question = null)
{
$this->question = $question;
return $this;
}
/**
* Get question
*
* #return \AppBundle\Entity\Question
*/
public function getQuestion()
{
return $this->question;
}
/**
* Set tag
*
* #param \AppBundle\Entity\Tag $tag
*
* #return QuestionTag
*/
public function setTag(\AppBundle\Entity\Tag $tag = null)
{
$this->tag = $tag;
return $this;
}
/**
* Get tag
*
* #return \AppBundle\Entity\Tag
*/
public function getTag()
{
return $this->tag;
}
}
question entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Question
*
* #ORM\Table(name="question", indexes={#ORM\Index(name="index_question_title", columns={"title"}), #ORM\Index(name="index_question_creation", columns={"creation_date"}), #ORM\Index(name="index_question_completed", columns={"completed"}), #ORM\Index(name="index_question_subject", columns={"subject"}), #ORM\Index(name="index_question_user", columns={"user_platform"})})
* #ORM\Entity
*/
class Question
{
/**
* #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=50, nullable=false)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="text", type="string", length=1000, nullable=true)
*/
private $text;
/**
* #var \DateTime
*
* #ORM\Column(name="creation_date", type="date", nullable=false)
*/
private $creationDate;
/**
* #var boolean
*
* #ORM\Column(name="completed", type="boolean", nullable=true)
*/
private $completed = '0';
/**
* #var integer
*
* #ORM\Column(name="level", type="integer", nullable=true)
*/
private $level = '1';
/**
* #var \AppBundle\Entity\Subject
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Subject", cascade={ "persist" })
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="subject", referencedColumnName="name")
* })
*/
private $subject;
/**
* #var \AppBundle\Entity\UserPlatform
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\UserPlatform", cascade={ "persist" })
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="user_platform", referencedColumnName="username")
* })
*/
private $userPlatform;
/**
* Set id
*
* #param string $id
*
* #return Question
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
*
* #return Question
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set text
*
* #param string $text
*
* #return Question
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* #return string
*/
public function getText()
{
return $this->text;
}
/**
* Set creationDate
*
* #param \DateTime $creationDate
*
* #return Question
*/
public function setCreationDate($creationDate)
{
$this->creationDate = $creationDate;
return $this;
}
/**
* Get creationDate
*
* #return \DateTime
*/
public function getCreationDate()
{
return $this->creationDate;
}
/**
* Set completed
*
* #param boolean $completed
*
* #return Question
*/
public function setCompleted($completed)
{
$this->completed = $completed;
return $this;
}
/**
* Get completed
*
* #return boolean
*/
public function getCompleted()
{
return $this->completed;
}
/**
* Set level
*
* #param integer $level
*
* #return Question
*/
public function setLevel($level)
{
$this->level = $level;
return $this;
}
/**
* Get level
*
* #return integer
*/
public function getLevel()
{
return $this->level;
}
/**
* Set subject
*
* #param \AppBundle\Entity\Subject $subject
*
* #return Question
*/
public function setSubject(\AppBundle\Entity\Subject $subject = null)
{
$this->subject = $subject;
return $this;
}
/**
* Get subject
*
* #return \AppBundle\Entity\Subject
*/
public function getSubject()
{
return $this->subject;
}
/**
* Set userPlatform
*
* #param \AppBundle\Entity\UserPlatform $userPlatform
*
* #return Question
*/
public function setUserPlatform(\AppBundle\Entity\UserPlatform $userPlatform = null)
{
$this->userPlatform = $userPlatform;
return $this;
}
/**
* Get userPlatform
*
* #return \AppBundle\Entity\UserPlatform
*/
public function getUserPlatform()
{
return $this->userPlatform;
}
}
tag entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Tag
*
* #ORM\Table(name="tag")
* #ORM\Entity
*/
class Tag
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=20)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
private $name = '';
/**
* Set name
*
* #param string $name
*
* #return tag
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
when I try to put a value into table question_tag I have this error:
An exception occurred while executing 'INSERT INTO tag (name) VALUES (?)' with params ["PYTHON"]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'PYTHON' for key 'PRIMARY'
Why?
It should not avoid entering a value if it already exists in the database? if this should be made explicit, how should I do?
thank you
In Symfony2 you have this things called Validators their job is to validate an object based on constraints so in your case you could use the following constraint in your tag entity
http://symfony.com/doc/current/reference/constraints/UniqueEntity.html
And then call to the validator service in your controller. You could avoid this step if you use FormTypes for your classes they automatically validate the object with the validator service.
http://symfony.com/doc/current/book/forms.html
Actually you could use the forms to validate data structure.. but that is offtopic
.....
The other way you could do this is by selecting the tag you want to insert and check if there is a result if not well then you can insert the tag if it exists you just recover it from the database and use the existing one
the problem was with the parameters that I give to the method to put data into db, so this code:
//the question with Id 1 exist already
$question = new Question();
$question->setId(1);
//the tag with name PYTHON exist already
$tag = new Tag();
$tag->setName("PYTHON");
$questionTag = new QuestionTag();
$questionTag->setQuestion($question);
$questionTag->setTag($tag);
//now I call a service to put the item into DB
$questionTagPF = $this->get('facade.QuestionTagFacade');
$res = $questionTagPF->create($questionTag);
have to be written so:
//the question with Id 1 exist already
$question = $this->getDoctrine()->getManager()->getReference('AppBundle:Question',"1");
//the tag with name PYTHON exist already
$tag = $this->getDoctrine()->getManager()->getReference('AppBundle:Tag',"PYTHON");
$questionTag = new QuestionTag();
$questionTag->setQuestion($question);
$questionTag->setTag($tag);
//now I call a service to put the item into DB
$questionTagPF = $this->get('facade.QuestionTagFacade');
$res = $questionTagPF->create($questionTag);
The problem was that to insert a value into a relation you have to take values through the manager!

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails .Symfony2.8

When i tried to update my database i got this error:
i'm not sure but I think the error means that the value for column tva_id on table fly
you are inserting doesn't exist on table tva. when i check in phpmyadmin tva(id)) should be link to(tva_id)` in table Post but is not. what should i do to fix this error ?
[Doctrine\DBAL\DBALException]
An exception occurred while executing 'ALTER TABLE post ADD CONSTRAINT
FK_5 A8A6C8D4D79775F FOREIGN KEY (tva_id) REFERENCES tva (id)':
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(fly.#sql-93c_155, CONSTRAI NT FK_5A8A6C8D4D79775F FOREIGN
KEY (tva_id) REFERENCES tva (id))
Tva.php
<?php
namespace FLY\BookingsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Tva
*
* #ORM\Table("tva")
* #ORM\Entity(repositoryClass="FLY\BookingsBundle\Entity\TvaRepository")
*/
class Tva
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var float
*
* #ORM\Column(name="multiplicate", type="float")
*/
private $multiplicate;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=125)
*/
private $name;
/**
* #var float
*
* #ORM\Column(name="value", type="float")
*/
private $value;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set multiplicate
*
* #param float $multiplicate
* #return Tva
*/
public function setMultiplicate($multiplicate)
{
$this->multiplicate = $multiplicate;
return $this;
}
/**
* Get multiplicate
*
* #return float
*/
public function getMultiplicate()
{
return $this->multiplicate;
}
/**
* Set name
*
* #param string $name
* #return Tva
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set value
*
* #param float $value
* #return Tva
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* #return float
*/
public function getValue()
{
return $this->value;
}
}
post.php
<?php
namespace FLY\BookingsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Application\Sonata\UserBundle\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use JMS\SecurityExtraBundle\Annotation\Secure;
/**
* Post
*
* #ORM\Table(name="post")
* #ORM\Entity(repositoryClass="FLY\BookingsBundle\Entity\PostRepository")
*/
class Post
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="FLY\BookingsBundle\Entity\Tva", cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $tva;
/**
*
*
* #ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User")
* #ORM\JoinColumn(onDelete="CASCADE")
* #Security("user.getId() == post.getOwner()")
*/
private $owner;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #return User
*/
public function getOwner()
{
return $this->owner;
}
/*
* #param User $owner
*/
public function setOwner(User $owner)
{
$this->owner = $owner;
return $this;
}
/**
* Set tva
*
* #param \FLY\BookingsBundle\Entity\Tva $tva
* #return Post
*/
public function setTva(\FLY\BookingsBundle\Entity\Tva $tva)
{
$this->tva = $tva;
return $this;
}
/**
* Get tva
*
* #return \FLY\BookingsBundle\Entity\Tva
*/
public function getTva()
{
return $this->tva;
}
}
user.php
<?php
namespace Application\Sonata\UserBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Sonata\UserBundle\Entity\BaseUser as BaseUser;
use ArrayIterator;
use Closure;
use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
/**
* This file has been generated by the Sonata EasyExtends bundle ( http://sonata-project.org/easy-extends )
*
*/
/**
* #ORM\Entity(repositoryClass="FLY\UserBundle\Repository\UserRepository")
* #ORM\Table(name="fos_user_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
$this->commandes = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #ORM\OneToMany(targetEntity="FLY\BookingsBundle\Entity\Commandes", mappedBy="user", cascade={"remove"})
* #ORM\JoinColumn(nullable=true)
*/
private $commandes;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add commandes
*
* #param \FLY\BookingsBundle\Entity\Commandes $commandes
* #return User
*/
public function addCommande(\FLY\BookingsBundle\Entity\Commandes $commandes)
{
$this->commandes[] = $commandes;
return $this;
}
/**
* Remove commandes
*
* #param \FLY\BookingsBundle\Entity\Commandes $commandes
*/
public function removeCommande(\FLY\BookingsBundle\Entity\Commandes $commandes)
{
$this->commandes->removeElement($commandes);
}
/**
* Get commandes
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCommandes()
{
return $this->commandes;
}
}

How to use getQuery()->getOneOrNullresult() return

in my test project I have 2 entities :
- endUser (extend of FOSUserBundle)
- Rezo (will containt approved relation between two members)
the both entities have been defined as :
EndUser Entity :
<?php
namespace Core\CustomerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;
/**
* EndUser
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Core\CustomerBundle\Entity\EndUserRepository")
*/
class EndUser extends BaseUser
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="firstname", type="string", length=255)
*/
private $firstname;
/**
* #var string
* #ORM\Column(name="lastname", type="string", length=255)
*/
private $lastname;
/**
* #var \DateTime
*
* #ORM\Column(name="DateNaissance", type="datetime", nullable=true)
*/
private $DateNaissance;
/**
* #ORM\OneToOne(targetEntity="Core\CustomerBundle\Entity\EndUser", cascade={"persist", "merge", "remove"})
* #ORM\JoinColumn(name="adressbook_id", referencedColumnName="id", nullable=true)
*/
private $adressbook;
/**
* #ORM\ManyToMany(targetEntity="Core\MyEquiBookBundle\Entity\Discipline", mappedBy="endusers")
*/
private $disciplines;
/**
* #ORM\ManyToMany(targetEntity="Core\MyEquiBookBundle\Entity\Experiences", mappedBy="endusers")
*/
private $experiences;
/**
* #var string
* #ORM\Column(name="avatar", type="string", length=255, nullable=true)
*/
private $avatar;
/**
* #var string
* #ORM\Column(name="repository", type="string", length=255, nullable=true)
*/
private $repository;
/**
* #ORM\OneToMany(targetEntity="Core\MyEquiBookBundle\Entity\NiveauEndUser", mappedBy="enduser", cascade={"remove", "persist"})
*/
protected $niveaux;
/**
* #ORM\OneToMany(targetEntity="Core\GeneralBundle\Entity\Rezo", mappedBy="enduser", cascade={"remove", "persist"})
*/
protected $friends;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->disciplines = new \Doctrine\Common\Collections\ArrayCollection();
$this->niveaux = new \Doctrine\Common\Collections\ArrayCollection();
$this->experiences = new \Doctrine\Common\Collections\ArrayCollection();
$this->friends = new \Doctrine\Common\Collections\ArrayCollection();
$this->expiresAt = new \DateTime("+1 year");
$this->credentialsExpireAt = new \DateTime("+1 year");
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set avatar
*
* #param string $avatar
* #return EndUser
*/
public function setAvatar($avatar)
{
$this->avatar = $avatar;
return $this;
}
/**
* Get avatar
*
* #return string
*/
public function getAvatar()
{
return $this->avatar;
}
/**
* Set repository
*
* #param string $repository
* #return EndUser
*/
public function setRepository($repository)
{
$this->repository = $repository;
return $this;
}
/**
* Get repository
*
* #return string
*/
public function getRepository()
{
return $this->repository;
}
/**
* Set adressbook
*
* #param \Core\CustomerBundle\Entity\EndUser $adressbook
* #return EndUser
*/
public function setAdressbook(\Core\CustomerBundle\Entity\EndUser $adressbook = null)
{
$this->adressbook = $adressbook;
return $this;
}
/**
* Get adressbook
*
* #return \Core\CustomerBundle\Entity\EndUser
*/
public function getAdressbook()
{
return $this->adressbook;
}
/**
* Add disciplines
*
* #param \Core\MyEquiBookBundle\Entity\Discipline $disciplines
* #return EndUser
*/
public function addDiscipline(\Core\MyEquiBookBundle\Entity\Discipline $disciplines)
{
$this->disciplines[] = $disciplines;
return $this;
}
/**
* Remove disciplines
*
* #param \Core\MyEquiBookBundle\Entity\Discipline $disciplines
*/
public function removeDiscipline(\Core\MyEquiBookBundle\Entity\Discipline $disciplines)
{
$this->disciplines->removeElement($disciplines);
}
/**
* Get disciplines
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDisciplines()
{
return $this->disciplines;
}
/**
* Add niveaux
*
* #param \Core\MyEquiBookBundle\Entity\NiveauEndUser $niveaux
* #return EndUser
*/
public function addNiveaux(\Core\MyEquiBookBundle\Entity\NiveauEndUser $niveaux)
{
$this->niveaux[] = $niveaux;
return $this;
}
/**
* Remove niveaux
*
* #param \Core\MyEquiBookBundle\Entity\NiveauEndUser $niveaux
*/
public function removeNiveaux(\Core\MyEquiBookBundle\Entity\NiveauEndUser $niveaux)
{
$this->niveaux->removeElement($niveaux);
}
/**
* Get niveaux
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getNiveaux()
{
return $this->niveaux;
}
/**
* Add experiences
*
* #param \Core\MyEquiBookBundle\Entity\Experiences $experiences
* #return EndUser
*/
public function addExperience(\Core\MyEquiBookBundle\Entity\Experiences $experiences)
{
$this->experiences[] = $experiences;
return $this;
}
/**
* Remove experiences
*
* #param \Core\MyEquiBookBundle\Entity\Experiences $experiences
*/
public function removeExperience(\Core\MyEquiBookBundle\Entity\Experiences $experiences)
{
$this->experiences->removeElement($experiences);
}
/**
* Get experiences
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getExperiences()
{
return $this->experiences;
}
/**
* Add friends
*
* #param \Core\GeneralBundle\Entity\Rezo $friends
* #return EndUser
*/
public function addFriend(\Core\GeneralBundle\Entity\Rezo $friends )
{
$this->friends[] = $friends;
return $this;
}
/**
* Remove friends
*
* #param \Core\GeneralBundle\Entity\Rezo $friends
*/
public function removeFriend(\Core\GeneralBundle\Entity\Rezo $friends)
{
$this->friends->removeElement($friends);
}
/**
* Get friends
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getFriends()
{
return $this->friends;
}
/**
* Set firstname
*
* #param string $firstname
* #return EndUser
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return EndUser
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set DateNaissance
*
* #param \DateTime $dateNaissance
* #return EndUser
*/
public function setDateNaissance($dateNaissance)
{
$this->DateNaissance = $dateNaissance;
return $this;
}
/**
* Get DateNaissance
*
* #return \DateTime
*/
public function getDateNaissance()
{
return $this->DateNaissance;
}
}
Rezo Entity :
<?php
namespace Core\GeneralBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Rezo
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Core\GeneralBundle\Entity\RezoRepository")
*/
class Rezo
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="RequestedDate", type="datetime")
*/
private $requestedDate;
/**
* #var \DateTime
*
* #ORM\Column(name="AcceptedDate", type="datetime", nullable=true)
*/
private $acceptedDate;
/**
* #ORM\ManyToOne(targetEntity="Core\CustomerBundle\Entity\Enduser", inversedBy="friends", cascade={"refresh"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $enduser;
/**
* #ORM\ManyToOne(targetEntity="Core\CustomerBundle\Entity\EndUser", cascade={"refresh"})
* #ORM\JoinColumn(name="friendwith", referencedColumnName="id")
*/
protected $friendwith;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set requestedDate
*
* #param \DateTime $requestedDate
* #return Rezo
*/
public function setRequestedDate($requestedDate)
{
$this->requestedDate = $requestedDate;
return $this;
}
/**
* Get requestedDate
*
* #return \DateTime
*/
public function getRequestedDate()
{
return $this->requestedDate;
}
/**
* Set acceptedDate
*
* #param \DateTime $acceptedDate
* #return Rezo
*/
public function setAcceptedDate($acceptedDate)
{
$this->acceptedDate = $acceptedDate;
return $this;
}
/**
* Get acceptedDate
*
* #return \DateTime
*/
public function getAcceptedDate()
{
return $this->acceptedDate;
}
/**
* Set enduser
*
* #param \Core\CustomerBundle\Entity\EndUser $enduser
* #return Rezo
*/
public function setEnduser(\Core\CustomerBundle\Entity\EndUser $enduser = null)
{
$this->enduser = $enduser;
return $this;
}
/**
* Get enduser
*
* #return \Core\CustomerBundle\Entity\EndUser
*/
public function getEnduser()
{
return $this->enduser;
}
/**
* Set friendwith
*
* #param \Core\CustomerBundle\Entity\EndUser $friendwith
* #return Rezo
*/
public function setFriendwith(\Core\CustomerBundle\Entity\EndUser $friendwith = null)
{
$this->friendwith = $friendwith;
return $this;
}
/**
* Get friendwith
*
* #return \Core\CustomerBundle\Entity\EndUser
*/
public function getFriendwith()
{
return $this->friendwith;
}
when I run :
app/console doctrine:schema:update --force
The following MySQL table has been created :
CREATE TABLE IF NOT EXISTS `Rezo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`friendwith` int(11) DEFAULT NULL,
`RequestedDate` datetime NOT NULL,
`AcceptedDate` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_681FC4BA76ED395` (`user_id`),
KEY `IDX_681FC4B1094AD75` (`friendwith`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
In the RezoController.php controller I would like to give to endUser opportunity to accept a contact request fot this I have created a function named : acceptnewrequestAction($id)
public function acceptnewrequestAction($id){
$em = $this->getDoctrine()->getManager();
$rezo = $em->getRepository('CoreGeneralBundle:Rezo')->find($id);
$user1 = $rezo->getEnduser();
$user2 = $rezo->getFriendwith();
$dateRequest = $rezo->getRequestedDate();
$rezo->setAcceptedDate(new \DateTime('now'));
$em->persist($rezo);
$em->flush();
/* check if inverse relation exist */
$query = $em->CreateQuerybuilder();
$query->select('t0.id');
$query->from('CoreGeneralBundle:Rezo','t0');
$query->where('t0.acceptedDate IS NULL');
$query->andWhere('t0.enduser = :userId');
$query->andWhere('t0.friendwith =:userId2');
$query->SetParameters(array('userId'=> $user2, 'userId2'=>$user1));
$result = $query->getQuery()->getOneOrNullResult();
if ( is_object($result))
{
$rezo = $em->getRepository('CoreGeneralBundle:Rezo')->findById($result->getId());
$rezo->setAcceptedDate(new \DateTime('now'));
} else {
$rezo = new Rezo();
$rezo->setRequestedDate(new \Datetime('now'));
$rezo->setAcceptedDate(new \DateTime('now'));
$rezo->Setenduser($user2);
$rezo->setFriendwith($user1);
}
$em->persist($rezo);
$em->flush();
return $this->render(controller('CoreGeneralBundle:Rezo:RezoList'));
}
I would like to know how I can use results to know if one object if found or return is Null and in case it exists update it or create a new one.
thank you for your help
getOneOrNullResult method tells you if any record in database is found, or not.
If it return null, it means that you have some results, and in your case you have to insert new one.
But when it exists some records, this method will return object instance of your entity. That means in your case you have to update existing record.
Please remember, that getOneOrNullResult method throws exception, when result set is not unique.

Symfony2 forms collection

I have, two entities, Topic and TopicContent are relation by topic_id.
topic_id in topic table is autoincremet , in topic_content it's not autoincrement.
Because, i need to get topic_id from Topic entity when query it's ok, and then insert data in topic_content table. Help me please, how to do this in symfony with orm. thanks.
TopicContent
namespace Socialist\ClubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="topic_content")
*/
class TopicContent
{
/**
*
* #ORM\Column(name="topic_id", type="integer")
* #ORM\Id
*
*/
protected $topic_id;
/**
*
* #ORM\Column(name="topic_text", type="text", nullable=false)
*/
protected $topic_text;
/**
* #ORM\OneToOne(targetEntity="Topic", inversedBy="topicContent", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="topic_id", referencedColumnName="topic_id", onDelete="CASCADE")
*/
private $topic;
/**
* Set topic_id
*
* #param integer $topicId
* #return TopicContent
*/
public function setTopicId($topicId)
{
$this->topic_id = $topicId;
return $this;
}
/**
* Get topic_id
*
* #return integer
*/
public function getTopicId()
{
return $this->topic_id;
}
/**
* Set topic_text
*
* #param string $topicText
* #return TopicContent
*/
public function setTopicText($topicText)
{
$this->topic_text = $topicText;
return $this;
}
/**
* Get topic_text
*
* #return string
*/
public function getTopicText()
{
return $this->topic_text;
}
/**
* Set topic
*
* #param \Socialist\ClubBundle\Entity\Topic $topic
* #return TopicContent
*/
public function setTopic(\Socialist\ClubBundle\Entity\Topic $topic = null)
{
$this->topic = $topic;
return $this;
}
/**
* Get topic
*
* #return \Socialist\ClubBundle\Entity\Topic
*/
public function getTopic()
{
return $this->topic;
}
}
Topic
namespace Socialist\ClubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="topic")
* #ORM\HasLifecycleCallbacks
*/
class Topic
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $topic_id;
/**
* #ORM\Column(type="string", length=200)
*/
protected $topic_title;
/**
* #ORM\Column(type="datetime")
*/
protected $topic_date_add;
/**
* #ORM\Column(type="datetime")
*/
protected $topic_date_edit;
/**
* Get topic_id
*
* #return integer
*/
public function getTopicId()
{
return $this->topic_id;
}
/**
* Set topic_title
*
* #param string $topicTitle
* #return Topic
*/
public function setTopicTitle($topicTitle)
{
$this->topic_title = $topicTitle;
return $this;
}
/**
* Get topic_title
*
* #return string
*/
public function getTopicTitle()
{
return $this->topic_title;
}
/**
* Set topic_date_add
*
* #param \DateTime $topicDateAdd
* #return Topic
*/
public function setTopicDateAdd($topicDateAdd)
{
$this->topic_date_add = $topicDateAdd;
return $this;
}
/**
* Get topic_date_add
*
* #return \DateTime
*/
public function getTopicDateAdd()
{
return $this->topic_date_add;
}
/**
* Set topic_date_edit
*
* #param \DateTime $topicDateEdit
* #return Topic
*/
public function setTopicDateEdit($topicDateEdit)
{
$this->topic_date_edit = $topicDateEdit;
return $this;
}
/**
* Get topic_date_edit
*
* #return \DateTime
*/
public function getTopicDateEdit()
{
return $this->topic_date_edit;
}
/**
* #ORM\PrePersist
*/
public function setTopicDateAddValue() {
if (!$this->getTopicDateAdd())
{
$this->topic_date_add = new \DateTime();
}
}
/**
* #ORM\PreUpdate
*/
public function setTopicDateEditValue()
{
$this->topic_date_edit = new \DateTime();
}
public function __construct()
{
$this->setTopicDateAdd(new \DateTime());
$this->setTopicDateEdit(new \DateTime());
}
/**
* #ORM\OneToOne(targetEntity="TopicContent", mappedBy="topic", cascade={"persist", "remove"})
*/
private $topicContent;
/**
* Set topicContent
*
* #param \Socialist\ClubBundle\Entity\TopicContent $topicContent
* #return Topic
*/
public function setTopicContent(\Socialist\ClubBundle\Entity\TopicContent $topicContent = null)
{
$this->topicContent = $topicContent;
return $this;
}
/**
* Get topicContent
*
* #return \Socialist\ClubBundle\Entity\TopicContent
*/
public function getTopicContent()
{
return $this->topicContent;
}
}
Topic Entity
public function __construct()
{
$this->topicContent = new \Doctrine\Common\Collections\ArrayCollection();
$this->setTopicDateAdd(new \DateTime());
$this->setTopicDateEdit(new \DateTime());
}
/**
* Set topicContent
*
* #param \Socialist\ClubBundle\Entity\TopicContent $topicContent
* #return Topic
*/
public function setTopicContent(\Socialist\ClubBundle\Entity\TopicContent $topicContent = null)
{
$this->topicContent = $topicContent;
return $this;
}
Topic Controller
public function createAction(Request $request)
{
$entity = new Topic();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('topic_show', array('id' => $entity->getTopicId())));
}
return $this->render('SocialistClubBundle:Topic:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
After persisting your Topic Entity, you will get LastInserted topic id from your Topic entity
for example,
$em = $this->getDoctrine()->getManager();
$topic = new \Acme\TestBundle\Entity\Topic();
$topic->setTopicTitle('Your Title');
$em->persist($topic);
$em->flush(); //insert data into table
If insertion is ok $topic entity hold new row object inserted
You can get new topic id by getting
$newTopicId= $topic->getTopicId();
For Topic content Entity,
$topicContent= new new \Acme\TestBundle\Entity\TopicContent();
$topicContent->setTopicId($newTopicId);
$topicContent->setTopicText('Your topic text');
For avoid more confusion Please change your Topic Content Entity as follows,
namespace Socialist\ClubBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="topic_content")
*/
class TopicContent
{
/**
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
*/
protected $id;
/**
*
* #ORM\Column(name="topic_text", type="text", nullable=false)
*/
protected $topic_text;
/**
* #ORM\OneToOne(targetEntity="Topic", inversedBy="topicContent", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="topic_id", referencedColumnName="topic_id", onDelete="CASCADE")
*/
private $topic;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set topic_text
*
* #param string $topicText
* #return TopicContent
*/
public function setTopicText($topicText)
{
$this->topic_text = $topicText;
return $this;
}
/**
* Get topic_text
*
* #return string
*/
public function getTopicText()
{
return $this->topic_text;
}
/**
* Set topic
*
* #param \Socialist\ClubBundle\Entity\Topic $topic
* #return TopicContent
*/
public function setTopic(\Socialist\ClubBundle\Entity\Topic $topic = null)
{
$this->topic = $topic;
return $this;
}
/**
* Get topic
*
* #return \Socialist\ClubBundle\Entity\Topic
*/
public function getTopic()
{
return $this->topic;
}
}`
The id should be primary key and autoincrement
this will resolve your all 'topic_id' burdens

Categories