So i have the following mapping:
Order entity
/**
* Order
*
* #ORM\Table(name="`order`")
* #ORM\Entity
*/
class Order
{
/**
* #var integer
*
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
// ... //
/**
* #ORM\OneToMany(targetEntity="OrderItem", mappedBy="order")
*/
private $items;
// ... //
OrderItem entity
/**
* OrderItem
*
* #ORM\Table(name="order_item")
* #ORM\Entity
*/
class OrderItem
{
/**
* #var integer
*
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
// ... //
/**
* #ORM\ManyToOne(targetEntity="Order", inversedBy="items")
* #ORM\JoinColumn(referencedColumnName="id")
*/
private $order;
// ... //
The problem I experience is when I try to dump $order->getItems() after flushing it remains NULL. Eveything is inserted fine to the database with the correct ids and when I try to get the order in the NEXT request it does contain items in $order->getItems() so no doubt it does work.
But it does not work (giving NULL) with the same request.
Look at the code below:
$manager = $this->getDoctrine()->getManager();
$order = new Order();
$orderItem = new OrderItem();
$orderItem
->setOrder($order)
;
$manager->persist($order);
$manager->persist($orderItem);
dump($order->getItems()); // returns NULL
// but in the next request it will contain items
So how can I get those items within the same request? I need to generate the order and return the items... any idea?
In class OrderItem, maybe.
public setOrder(Order $order)
{
$order->addItem($this);
$this->ordder = $order;
}
Related
I tried to transform a SQL function into DQL but i always have errors...
I have 3 tables
/**
* #ORM\Entity(repositoryClass=ArticleRepository::class)
*/
class Article
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $title;
/**
* #Gedmo\Slug(fields={"title"})
* #ORM\Column(type="string", length=255, unique=true, nullable=true)
*/
private $slug;
/**
* #ORM\Column(type="boolean", options={"default":"0"})
*/
private $isItalian = false;
/**
* #ORM\Column(type="text")
*/
private $content;
/**
* #ORM\ManyToMany(targetEntity=Contact::class, inversedBy="viewedArticles")
*/
private $contact;
}
class Contact implements UserInterface, JsonSerializable
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
protected ?int $id = null;
/**
* #ORM\Column(type="string", length=255, unique=true)
*/
protected ?string $email = null;
/**
* #ORM\ManyToMany(targetEntity=Article::class, mappedBy="contact")
*/
private $viewedArticles;
}
And a many to many table
article_contact (a manyToMany table) with article_id and contact_id
i want to get all articles who are not in the article_contact table (it's all the articles who're not viewed by the contact)
I tried this request in SQL and it works, but it return an array and i need to return an object to use it in Symfony
$conn = $entityManager->getConnection();
$sql = 'SELECT *
FROM article
LEFT JOIN article_contact
ON article.id = article_id
AND contact_id = '.$id.'
WHERE article.is_italian = '.$isItalian.'
AND article_id IS NULL';
$stmt = $conn->prepare($sql);
$result = $stmt->executeQuery();
return $result->fetchAllAssociative();
DQL request :
return $this->createQueryBuilder('a')
->leftJoin('a.contact', 'contact')
->where('a.isItalian = 0')
->andWhere('contact = 1')
->andWhere('contact.viewedArticles IS NULL')
->getQuery()
->getResult()
;
it's the ->andWhere('contact.viewedArticles IS NULL') part who's not working, i have this error
[Semantical Error] line 0, col 113 near 'viewedArticles': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
The answer is
$qb->select('a')
->from(Article::class,'a')
->leftJoin('a.contact', 'contact', 'WITH', 'contact.id = :id')
->setParameter('id', $contactId)
->andWhere('a.isItalian = :isItalian')
->setParameter('isItalian', $isItalian)
->groupBy('a.id')
->having('COUNT(contact.id) = 0')
;
return $qb->getQuery()->getResult();
Thanks to Will B. !
The application has built in ZF3. I have to entity with ManyToOne relationship using ORM. The issue is when i render through controller and and if fetch data via index it gives okay result but when i assign that to view and trying to render at phtml it throws an error/
/**
* Subscriptions
*
* #ORM\Table(name="subscriptions", indexes={#ORM\Index(name="CUST_ID", columns={"customer_id"}),#ORM\Index(name="SUB_TYPE_ID", columns={"subscription_type_id"})})
* #ORM\Entity
*/
class Subscriptions
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Application\Entity\SubscriptionType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SubscriptionType")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="subscription_type_id", referencedColumnName="id")
* })
*/
protected $subscriptionType;
//set
public function setSubscriptionType(\Application\Entity\SubscriptionType $subscriptionType = null)
{
$this->subscriptionType = $subscriptionType;
return $this;
}
//get
public function getSubscriptionType(){
return $this->subscriptionType;
}
//other setter and getter....
}
Another Class
/**
* SubscriptionType
*
* #ORM\Table(name="subscription_type")
* #ORM\Entity
*/
class SubscriptionType
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="description", type="text", length=65535, nullable=true)
*/
private $description;
/**
* Get id
*enter code here
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
*
* #return SubscriptionType
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
}
Now at controller i have wrote...
//some initiations
class AdminController extends AbstractActionController
{
//other initiations including __construct....
public function usersubscriptionsAction(){
$this->subscriptions = $this->entityManager->getRepository(Subscriptions::class)->findAll();
/*
foreach($this->subscriptions as $subscription){
//if i am checking with this it gives proper output
echo $subscription->getSubscriptionType()->getDescription();
die();
}
*/
return new ViewModel(
array(
"subscriptions" => $this->subscriptions
)
);
}
}
///i have phtml file
<?php foreach ($subscriptions as $subscription): ?>
//below line throwing an error
<?php echo $subscription->getSubscriptionType()->getDescription(); ?>
<?php endforeach; ?>
when i run it throw an erro message
Call to a member function getDescription() on null
You've got the relation mapping incorrect. Corrected the property annotation below:
/**
* #var \Application\Entity\SubscriptionType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SubscriptionType")
* #ORM\JoinColumn(name="subscription_type_id", referencedColumnName="id")
*/
protected $subscriptionType;
You had
/**
* #var \Application\Entity\SubscriptionType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\SubscriptionType")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="subscription_type_id", referencedColumnName="id")
* })
*/
protected $subscriptionType;
The #ORM\JoinColumns is used for when you have a join with multiple columns, please see the docs. Though, the most common usage of JoinColumns is for a JoinTable.
I'm trying to insert a line to my base, from postman to a local api with some foreign keys and I have this bug :
"message": "Invalid data \"1\"(AppBundle\Entity\InterventionType),
expected \"AppBundle\Entity\Intervention\"."
It pointed to the bad Entity and I don't know why. I'm targeting "Intervention", and doctrine seems to go in InterventionType...
Here's my entity :
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use \DateTime;
/**
* InterventionRapport
*
* #ORM\Table(name="intervention_rapport", options={"comment":"Table répertoriant les retours associés aux différentes interventions (commerciales et techniques) - Egalement utilisée pour rémunérer les techniciens et calculer les frais kilométriques tech/com"})
* #ORM\Entity
*/
class InterventionRapport
{
/**
* #var integer
* #ORM\OneToOne(targetEntity="AppBundle\Entity\Intervention")
* #ORM\JoinColumn(name="intervention", nullable=false)
*/
private $intervention;
/**
* #var string
*
* #ORM\Column(name="message", type="text", nullable=true)
*/
private $message;
/**
* #var integer
*
* #ORM\Column(name="statut", type="integer", nullable=false)
*/
private $statut = '0';
/**
* some other things
**/
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
}
and the entity targeted with foreign key:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Intervention
*
* #ORM\Table(name="intervention")
* #ORM\Entity
*/
class Intervention
{
/**
* #var integer
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\InterventionType")
* #ORM\JoinColumn(name="type", nullable=false)
*/
private $type;
/**
* Some other things
**/
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
}
And finally my json:
{
"message": "Steuh plait !",
"statut": 1,
"datemaintenanceprevue": "2017-08-23T15:00:00+00:00",
"heuresintervention": 1,
"heurestrajet": 0.5,
"kmtrajet": 27,
"deleted": 0,
"intervention": 1,
"id": 2
}
Please help, what am I doing wrong?
I found a slution by changing the way I created the line. I don't put the intervention id directly, I pass it into the url :
class RapportController extends Controller
{
/**
* #Rest\Post(
* path = "/reports/intervention={id}",
* name = "app_report_create"
* )
* #Rest\View(StatusCode = 201)
* #ParamConverter("report", converter="fos_rest.request_body")
*/
public function createAction(Request $request, InterventionRapport $report)
{
$em = $this->getDoctrine()->getManager();
$intervention = $this->get('doctrine.orm.entity_manager')
->getRepository('AppBundle:Intervention')
->find($request->get('id'));
//$report = new \DateTime($datemaintenanceprevue);
$report->setIntervention($intervention);
$em->persist($report);
$em->flush();
return $report;
}
So, I don't need to post the intervention id from my client' json :
{
"message": "Steuh plait !",
"statut": 1,
"datemaintenanceprevue": "2017-08-23T15:00:00+00:00",
"heuresintervention": 1,
"heurestrajet": 0.5,
"kmtrajet": 27,
"deleted": 0,
"id": 2
}
I don't know if it's the correct way to do it, but it solved the problem. Hope it can help someone else.
i can't to do true query from 2 tables.
/**
* 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;
and client entity have id, name, surname parameters:
I want to do search by orders column, and by client parameters how i can which query?)
only for orders work this:
$queryBuilder = $this->createQueryBuilder('c')
->orWhere('c.orderNumber LIKE :term')
->orWhere('c.device LIKE :term')
->setParameter('term', '%'.$term.'%');
You have to make a query with a join, which is possible with the querybuilder but i like to use DQL.
public function findOrdersOnClientName($searchTerm)
{
return $this->getEntityManager()->createQuery(
'SELECT o, c FROM AppBundle:OrderWork o
JOIN o.client c
WHERE c.name LIKE :term'
)->setParameter('term, '%'. $searchTerm . '%')->getResult();
}
I have spent the last day trying to find a solution to a problem that I am having and now turn to you to see if you can offer some advice.
Ill start with the table and then the entity
I have three tables,
table_a
table_b
table_c
each table row has a unique id
table_c contains a reference to table_a_id and to table_b_id
This reference should be unidirectional as table_a and table_b have no need to ever know of table_c's existence.
Also, there is no cascading, if an id from table_a or table_b does not exist, then table_c should not be able to insert a row.
ok, now for entities. (I am going to cut out irrelevant code to keep it short)
Entity A defines table_a
/**
* A
* #ORM\Entity(repositoryClass="Sample\Bundle\MyBundle\Entity\ARepository")
* #ORM\Table("table_a")
*/
class A
{
/**
* #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)
*/
private $name;
/**
* Get id
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
* #param string $name
* #return A
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
* #return string
*/
public function getName()
{
return $this->name;
}
}
Entity B defines table_b
/**
* B
*
* #ORM\Table("table_b")
* #ORM\Entity
*/
class B
{
/**
* #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)
*/
private $name;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
* #param string $name
* #return B
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
* #return string
*/
public function getName()
{
return $this->name;
}
}
Entity C maps table_c and has many to one relationships with table_a and table_b
/**
* C
*
* #ORM\Table("table_c")
* #ORM\Entity(repositoryClass="Sample\Bundle\MyBundle\Entity\CRepository")
*/
class PricesAverage
{
/**
* #var integer
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Sample\Bundle\MyBundle\Entity\A
* #ORM\ManyToOne(targetEntity="Sample\Bundle\MyBundle\Entity\A", inversedBy="id")
* #ORM\JoinColumn(name="a_id",unique=false)
*/
private $a;
/**
* #var \Sample\Bundle\MyBundle\Entity\B
* #ORM\ManyToOne(targetEntity="Sample\Bundle\MyBundle\Entity\B", inversedBy="id")
* #ORM\JoinColumn(name="b_id",unique=false)
*/
private $b;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #return A
*/
public function getA() {
return $this->a;
}
/**
* #param A $a
* #return $this
*/
public function setA($a) {
$this->a = $a;
return $this;
}
/**
* #return B
*/
public function getB() {
return $this->b;
}
/**
* #param B $b
* #return $this
*/
public function setB($b) {
$this->b = $b;
return $this;
}
}
No what I do is the following. (this is just simplified logic but it is the same process)
$days = 5;
$aCollection = {get collection of A's)
for($i = 0,$i<$days,$i++){
foreach($aCollection as $a){
$b = {get a single b}
$c = new C();
$c->setA($a)
->setB($b);
{use doctrine to persist and flush $c}
}
}
What is happening is that on the first insert the id for a is correct, but on the second insert, doctrine seems to think that competitor is a new entity and tries to persist and create a new id.
I have dumped my collection without activating the doctrine insert and I see that the id on A is correct, I then do the same thing after doctrine and find that doctrine is somehow clearing away my object.
How can I resolve this?
UPDATE:
I resolved this issue.
The problem that I was having is that the related entity was being removed from the entity manager after I did my batch insert.
The was a result of doing clear after every flush.
I moved clear to the end of the process so I flush as much as I need but only clear once.