Doctrine2 SQLSTATE[42000]: Syntax error or access violation: 1064 - mysql

User.php;
<?php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="like")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="itemtype", type="integer")
* #ORM\DiscriminatorMap({
* "1" = "LikeArticle",
* "2" = "LikePage",
* "3" = "LikeSite",
* })
*/
class Like
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="integer")
*/
protected $userid;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="likes")
* #ORM\JoinColumn(name="userid", referencedColumnName="id")
*/
protected $user;
}
LikePage.php;
<?php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="like_page")
*/
class LikePage extends Like
{
/**
* #ORM\Column(type="integer")
*/
protected $itemid;
/**
* #ORM\ManyToOne(targetEntity="Page", inversedBy="likes")
* #ORM\JoinColumn(name="itemid", referencedColumnName="id")
*/
protected $page;
LikeArticle.php;
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="like_article")
*/
class LikePage extends Like
{
/**
* #ORM\Column(type="integer")
*/
protected $itemid;
/**
* #ORM\ManyToOne(targetEntity="Article", inversedBy="likes")
* #ORM\JoinColumn(name="itemid", referencedColumnName="id")
*/
protected $article;
I add data to the database in this way. I'm trying to retrieve data from the Page Entity. But, When executing this;
$likes = $page->getLikes();
foreach($likes as $like) {
}
I am getting this error;
An exception occurred while executing 'SELECT t0.id AS id1, t0.userid AS userid2, t0.itemid AS itemid3, t0.userid AS userid4, t0.itemid AS itemid5, t0.itemtype FROM like t0 WHERE t0.itemid = ? AND t0.itemtype IN ('1')' with params [1]:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'like t0 WHERE t0.itemid = '1' AND t0.itemtype IN ('1')' at line 1
In this case what should I do? Why not find itemid?

like is a reserved word,escape it or better yet change your table name.
Docs
Change it to
* #ORM\Table(name="`like`")

Related

Symfony doctrine join related entities to discriminator columns

RoundMatch.php
/**
* #ORM\Entity(repositoryClass="MyApp\MyBundle\Repository\RoundMatchRepository")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"team_round_match" = "TeamRoundMatch", "player_round_match" = "PlayerRoundMatch"})
* #ORM\Table("my_round_match")
*/
abstract class RoundMatch
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \DateTime
*
* #ORM\Column(name="match_date", type="datetime")
*/
private $matchDate;
How can I join related entities to discriminated entities?
I cannot get direct access to discriminated table columns to create joins.
I cannot get access to discriminated table columns to create joins.
How can I join children entities to discriminator entities?
I created joins like this:
RoundMatchRepository.php
public function getMatchesWithNoResultsSubmitted()
{
$qb = $this->createQueryBuilder("rm");
$qb->leftJoin("rm.round", "rnd" )
->leftJoin("rnd.group", "sg")
->leftJoin("sg.server", "ss")
->leftJoin("ss.stage", "ts")
->leftJoin("ts.tournament", "t")
->leftJoin("MyAppMyBundle:PlayerRoundMatch", "prm", "WITH", "rm.id = prm.id")
->leftJoin("prm.player1", "p1")
->leftJoin("prm.player2", "p2")
->leftJoin('p1.gameProfiles',"gp1")
->leftJoin('p2.gameProfiles',"gp2")
->leftJoin('p1.gameProfiles', 'gp1', "WITH", $qb->expr()->andX(
$qb->expr()->eq('t.game', 'gp1.game'),
$qb->expr()->eq('prm.player1', 'gp1.player')
))
->leftJoin('p1.gameProfiles', 'gp2', "WITH", $qb->expr()->andX(
$qb->expr()->eq('t.game', 'gp2.game'),
$qb->expr()->eq('prm.player2', 'gp2.player')
));
return $qb->getQuery()->getResult();
}
I want to use result object in a twig and I cannot get joined entities in returned object because they are not joined via object relation.
I don't have object relation created because they are joined one to one via discriminator.
I have achieved dynamic relationships using Single Table Inheritance. This will allow you to write DQL against the relation or against the discriminating class.
You CANNOT "query" the discriminator using DQL. You must INSTANCE OF the entity name, see possible duplicate as per #LBA's comment
In this resulting schema, group_id will mean a different relation depending on the discriminator.
Obviously, this has performance implications on the database, though.
/**
* #ORM\Entity
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="type", type="string", length=255)
* #ORM\DiscriminatorMap(
* {"parents" = "Parents", "children" = "Child"}
* )
* #ORM\Table("people")
*/
class Person
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var mixed
*/
private $group;
}
/*
* #ORM\Table("parents")
*/
class Parent extends Person
{
/**
* Many parents have one group.
*
* #ManyToOne(targetEntity="ParentGroups", inversedBy="parents")
* #JoinColumn(name="group_id", referencedColumnName="id")
*/
private $group;
}
/*
* #ORM\Table("children")
*/
class Child extends Person
{
/**
* Many children have one group.
*
* #ManyToOne(targetEntity="ChildGroups", inversedBy="children")
* #JoinColumn(name="group_id", referencedColumnName="id")
*/
private $group;
}
/*
* #ORM\Table("parent_groups")
*/
class ParentGroups
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* One group has many parents.
*
* #OneToMany(targetEntity="Parent", mappedBy="group")
*/
private $parents;
public function __construct() {
$this->parents = new ArrayCollection();
}
}
/*
* #ORM\Table("child_groups")
*/
class ChildGroups
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* One group has many parents.
*
* #OneToMany(targetEntity="Child", mappedBy="group")
*/
private $children;
public function __construct() {
$this->children = new ArrayCollection();
}
}
Effectively the extending tables can override the annotations (if any) of the parent.
It work's a dream and we have multiple uses of this on our monolith :)
Untested code, but it should give you an idea of how I achieved it. If you struggle from here I'll go and make sure it runs.

fetching from ManyToMany table

I'm trying to fetch results from mysql table
I'm using symfony3 and of course doctrine 2
I have 2 entity Client.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\JoinColumn;
/**
* Client
*
* #ORM\Table(name="client")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ClientRepository")
*/
class Client
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="cin", type="integer")
*/
private $cin;
/**
* #ManyToMany(targetEntity="
* #JoinTable(name="listesouhait",
* joinColumns={#JoinColumn(name="utilisateur_id",
referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="evenement_id",
referencedColumnName="id")}
* )
*/
private $evenements;
public function __construct() {
$this->groups = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set cin
*
* #param integer $cin
*
* #return Client
*/
public function setCin($cin)
{
$this->cin = $cin;
return $this;
}
/**
* Get cin
*
* #return int
*/
public function getCin()
{
return $this->cin;
}
/**
* Add evenement
*
* #param \AppBundle\Entity\Evenement $evenement
*
* #return Client
*/
public function addEvenement(\AppBundle\Entity\Evenement $evenement)
{
$this->evenements[] = $evenement;
return $this;
}
/**
* Remove evenement
*
* #param \AppBundle\Entity\Evenement $evenement
*/
public function removeEvenement(\AppBundle\Entity\Evenement $evenement)
{
$this->evenements->removeElement($evenement);
}
/**
* Get evenements
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEvenements()
{
return $this->evenements;
}
}
and Evenement.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\ManyToOne;
use Doctrine\ORM\Mapping\JoinColumn;
/**
* Evenement
*
* #ORM\Table(name="evenement")
* #ORM\Entity(repositoryClass="AppBundle\Repository\EvenementRepository")
*/
class Evenement
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
//all attributes
when executing php bin\console doctrine:schema:update --force
image source
now everything is fine
but i can't find a clear code to insert in my controllerAction to fetch all the records in table listeshouhait (which is being generated automatically) because the table listeshouhait is not a real entity
also to mention that my repository are empty
i've heard of DQL in Repository and it might be helpful
Can SO help me please ??
To get the list of events attached to a client, in your controller :
$em = $this->getDoctrine()->getManager();
// Récupérer le client qui a l'id = 1
$item = $em->getRepository('AppBundle:Client')->findOneById(1);
// Liste des evenements
$events = $item->getEvenements();
foreach ($events as $event)
{
echo $event->getId() .'<br>';
}
die;

Doctrine add existing foreign keys when schema is updated (mysql)

I have the following entities:
A.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="a")
* #ORM\Entity()
*/
class A
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* One Cart has One Customer.
* #ORM\OneToOne(targetEntity="B", inversedBy="a")
* #ORM\JoinColumn(name="b_id", referencedColumnName="id")
*/
private $b;
/**
* #ORM\OneToOne(targetEntity="C", inversedBy="a")
* #ORM\JoinColumn(name="c_id", referencedColumnName="id")
*/
private $c;
/**
* #ORM\ManyToOne(targetEntity="D", inversedBy="a")
* #ORM\JoinColumn(name="d_id", referencedColumnName="id")
*/
private $d;
}
B.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="b")
* #ORM\Entity()
*/
class B
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="A", mappedBy="b")
*/
private $a;
}
C.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="c")
* #ORM\Entity()
*/
class C
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToOne(targetEntity="A", mappedBy="c")
*/
private $a;
}
D.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="d")
* #ORM\Entity()
*/
class D
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="A", mappedBy="d")
*/
private $a;
}
I executing commands:
php bin/console doctrine:database:create
php bin/console doctrine:schema:update --force
php bin/console doctrine:schema:update --dump-sql
Last command prints:
ALTER TABLE a ADD CONSTRAINT FK_E8B7BE43296BFCB6 FOREIGN KEY (b_id) REFERENCES b (id);
But this constraint is added before, so I can't to use
php bin/console doctrine:schema:update --force
Two times without error.
This behavior occurs only when I am using MySQL. When I removed MySQL and installed MariaDB problem vanished.
Should I introduce changes in my entities, or is it bug of Doctrine?
It seems a bug. Try using DoctrineMigrations bundle so that you can control migration classes before applying them.

Table partinioning (horizontal) with doctrine

I am using Doctrine 2.4 and I want to split the table one of my entity is using into several tables to improve querying that table - Horizontal partitioning, if I am not mistaken. The table has a lot of data (> 20 Mio. rows) and queries are always done on a subset (Component.Type).
Here are my entities:
Station:
/**
* #ORM\Id
* #ORM\Column(type="bigint")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
Component:
/**
* #ORM\Id
* #ORM\Column(type="bigint")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $type;
Data
/**
* #ORM\Id
* #ORM\Column(type="bigint")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="datetime")
*/
private $datetime;
/**
* #ORM\Column(type="float", nullable=true)
*/
private $value;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Station")
* #ORM\JoinColumn(name="station_id", referencedColumnName="id")
*
* #var Station $station
*/
private $station;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Component")
* #ORM\JoinColumn(name="component_id", referencedColumnName="id")
*
* #var Component $component
*/
private $component;
At the moment I solved this manually by having one Entity Data[TYPE] for every Component.Type (e.g. DataPollutionNo). All entities Data[TYPE] extent a MappedSuperclass (Data). To query for data, I first get the corresponding Data Entity from the Component.Type and query that Repository (DataPollutionNoRepository). This works out fine but I was wondering if there is a more sophisticated/generic approach to solve this.
Thanks, Hannes

Symfony2 - Doctrine - Join 2 tables

I'm having issues setting up my Doctrine request properly.
I have two tables (PROPRIETE and PHOTO), one PROPRIETE can have many PHOTO
Therefore, I'd like to make a SELECT that will return an array of PROPRIETE where which one includes an array of it's own PHOTOs (not sure if I'm clear though...)
This is what my Popriete class looks like
class Propriete
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="libelle", type="string", length=255)
*/
private $libelle;
/**
* #ORM\ManyToOne(targetEntity="VillaPrivee\UserBundle\Entity\User")
* #ORM\JoinColumn(onDelete="CASCADE")
*/
private $proprietaire;
/**
* #ORM\OneToMany(targetEntity="VillaPrivee\MainBundle\Entity\Photo", mappedBy="propriete")
*/
private $photo;
And then the Photo class
class Photo
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
/**
* #ORM\ManyToOne(targetEntity="VillaPrivee\MainBundle\Entity\Propriete")
* #ORM\JoinColumn(onDelete="CASCADE")
*/
private $propriete;
And finally, my Doctrine request (that successfully returns a list of Propriete, but nothing about their photos)
public function getProprietesByCriteria($ville, $rooms) {
$qb = $this->createQueryBuilder('p');
$qb->where('p.commune = :ville AND p.nbChambres >= :rooms')
->setParameter('ville', $ville)
->setParameter('rooms', $rooms);
return $qb->getQuery()->getResult();
}
I've tried with a leftJoin, but it seems that I don't know how to use that stuff...
Thanks guys for your help
I thing you're mixing different concepts in your code. Using Doctrine you should forget about trying to get multiple arrays with a query.
You only need to invoke the getPhoto() method on any propriete object.
So, you can use a code similar to:
$props = $this->getProprietesByCriteria($ville, $rooms);
foreach($props as $prop)
{
$prop->getPhoto(); // <--will return an array of the `PHOTO` related to this `PROPIETE`
}