I am trying Symfony 4 and I can't get this query right. The same thing worked OK in Symfony 3. I have 2 entities. One is a person and the other is a day. The relation is ManyToMany. I would like to get all days for a specific person
I tried using MEMBER OF and joining tables, but nothing works for this example.
// Day entity
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Person", inversedBy="days")
*/
private $person;
// Person entity
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Day", mappedBy="person")
*/
private $days;
// Repository function
return $this->createQueryBuilder('d')
->andWhere('d.person = :person')
->setParameter('person', $person)
->getQuery()
->getResult()
;
This is the error I get:
In QueryException.php line 65: [Semantical Error] line 0, col 58 near
'person = :pe': Error: Invalid PathExpression.
StateFieldPathExpression or SingleValuedAssociationField expected.
In QueryException.php line 43:
SELECT d FROM App\Entity\Day d WHERE d.date = :date AND d.person =
:person
The issue is not about Symfony version it's about orm version, i guess
So you could try this by using IDENTITY
return $this->createQueryBuilder('d')
->andWhere('IDENTITY(d.person) = :person')
->setParameter('person', $person)
->getQuery()
->getResult()
;
or
return $this->createQueryBuilder('d')
->leftJoin('d.person', 'p')
->andWhere('p.id = :person')
->setParameter('person', $person)
->getQuery()
->getResult()
;
You can get person related days just from association like $person->getDays()
Related
In symfony 5, with doctrine I want to create a request to select distinct type.
So, I have made the following code:
/**
* #Route("/hometest", name="hometest")
*/
public function index2()
{
$lesservices = $this->getDoctrine()->getRepository(Services::class)->findAll();
$em = $this->getdoctrine()->getManager();
$query = $em->createQuery('SELECT distinct serv.souscategorie FROM App\Entity\Services serv');
$services = $query->getResult();
return $this->render('home/indextest.html.twig', array ('servicesliste' => $lesservices, 'distinctscat' => $query));
}
But, I am getting this error :
[Semantical Error] line 0, col 21 near 'souscategorie': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
In fact, souscategorie is a relation field and if I put a string field at his place everything goes right.
Do I have to make a join request to have my souscategorie results ?
Thanks for your answers.
You are selecting a relation field, this might be your problem.
By searching your error i found out this answer which could help you solve your query without having to join:
SELECT DISTINCT IDENTITY(serv.souscategorie) ...
I have two classes related via a OneToMany bidirectional relationship. For every subscription a new line will be added to Subscriptions table. I want to get the training list ordered by max subscription number. Here are my entities:
Trainings Entity:
class Trainings
{
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Subscriptions", mappedBy="id_training")
*/
private $subscriptions_lists;
// ...
}
Subscriptions Entity:
class Subscriptions
{
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Trainings" , inversedBy="subscriptions_lists")
* #ORM\JoinColumn(name="id_training", referencedColumnName="id",onDelete="CASCADE")
*/
private $id_training;
QueryBuilder:
$trainings = $em->getRepository('AppBundle:Trainings')
->createQueryBuilder('t')
->innerJoin('t.subscriptions_lists', 'subscription')
->orderBy('COUNT(subscription.id)', 'DESC')
->getQuery()
->getResult();
I'm getting this exception:
[Syntax Error] line 0, col 87: Error: Expected known function, got 'COUNT'
You need to add a field containing the count value and after order by It
try this:
$trainings = $em->getRepository('AppBundle:Trainings')
->createQueryBuilder('t');
$trainings->select('t, COUNT(subscription.id) AS mycount')
->leftJoin('t.subscriptions_lists', 'subscription')
->groupBy('subscription.id_training')
->orderBy('mycount', 'DESC')
->getQuery()
->getResult();
I'm trying to get my head around the entity annotations for a doctrine one to many relationship.
For example, if table_one (T1) is:
email_address (string)
and table_two (T2) is
userid_email (string)
entry (int)
(email_address.table_one = userid_email.table_two) and there are multiple entries in table_two i.e
userid_email=test#email.com,entry=5;
userid_email=test#email.com,entry=6
Do I create the annotation for the T1 Entity
/**
* #ORM\ManyToMany(targetEntity="T1")
* #ORM\JoinTable(name="table_two",
* joinColumns={#ORM\JoinColumn(name="userid", referencedColumnName="userid_email")}
* )
*/
protected entries;
public function __construct()
{
$this->entries = new ArrayCollection();
}
And then in a createQuery I query on T1 :
$query = $em->createQuery('
SELECT u.email, u.entries
FROM AppBundle:T1 u
WHERE u.email = :an_email_address');
For the above query I would always get this error :
Error: Invalid PathExpression. Must be a StateFieldPathExpression
Is there something I am setting up improperly for the relationship?
Your configuration seems to be wrong, try something like:
/**
* #ORM\ManyToMany(targetEntity="T1")
* #ORM\joinColumn={#ORM\JoinColumn(name="userid", referencedColumnName="userid_email")}
* )
*/
I've ManyToOne relationship in doctrine (Many results to One PollingStation):
/**
* #ORM\ManyToOne(targetEntity="Iballot\CmsBundle\Entity\PollingStation2", inversedBy="results", cascade={"persist"})
* #ORM\JoinColumn(nullable=false)
* #Expose
*/
private $pollingStation2;
I'd like search for all the result that belong to the polling Station that have a name similar to a key word. I try the following method but it does not work:
public function getForSearch($keyWord)
{
$query = $this->_em->createQueryBuilder();
$query
->select('r')
->from('IballotCmsBundle:Result', 'r')
->where($query->expr()->like('p.pollingStation2', $query->expr()->literal('%' . $keyWord . '%')))
//->orderBy('p.', 'ASC')
->getQuery()
->setParameter('keyWord', '%'.$keyWord.'%');
return $query->getQuery()->getResult();
}
I get the following error
[Semantical Error] line 0, col 48 near 'pollingStation2': Error:
Invalid PathExpression. Must be a StateFieldPathExpression.
As said by #Cerad (one more time), you need a JOIN to make the associated entity available while building your query.
Try this :
$query = $this->_em->createQueryBuilder();
$query
->select('r')
->from('IballotCmsBundle:Result', 'r')
->leftJoin('r.pollingStation2', 'p') // The missing join
->where('p.name LIKE :keyword') // where p.name like %keyword%
->setParameter('keyword', '%'.$keyword.'%')
->orderBy('p.name', 'ASC') // order by p.name ASC
->getQuery()
return $query->getResult();
BTW I fixed your orderBy, simplified your where and fixed the keyword parameter that is wrongly defined.
Try putting this method in your Result EntityRepository class:
public function getForSearch($keyWord)
{
$query = $this->createQueryBuilder('r');
$query
->join('r.pollingStation2', 'p')
->where('p.name LIKE :keyword')
->setParameter('keyword', '%' . $keyWord . '%')
//->orderBy('p.', 'ASC')
;
return $query->getQuery()->getResult();
}
I have two entities in a OneToMany relationship, Perfil and IPerfil. Perfil can have several IPerfil's associated:
>
class Perfil
{
/**
* #var integer $id
*
* #ORM\Column(name="id_perfiles", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="P360.perfiles_seq")
* #ORM\OneToMany(targetEntity="IPerfil", mappedBy="id")
*/
private $id;
And the other one:
>
class IPerfil
{
/**
* #var integer $id
* #ORM\ManyToOne(targetEntity="Perfil")
* #ORM\JoinColumn(name="id_perfiles", referencedColumnName="id_perfiles", onDelete="CASCADE")
*/
protected $id;
I'm able to lazyload from IPerfil to Perfil, but not in the other direction (from Perfil to IPerfil), but if I can't do any DQL over IPerfil or createQueryBuilder()->setPameter... Symfony will always return an error like this:
[Semantical Error] line 0, col 9 near 'id_perfiles FROM': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
If I define the field Id with an
#ORM\Column(name="id_perfiles", type="integer")
Then I'm able to build DQL's with the entity, but the relationship won't work anymore.
I'm lost around here... It seems I'm missing something in the relationship definition, but have no clue.
Thanks in advance for any tip.
EDIT
If I use:
$entities=$em->getRepository('usuariosBundle:IPerfil')->findAll(array());
It doen'st gives an error, but I need to filter and order the results.
$entities=$em->getRepository('usuariosBundle:IPerfil')->findBy(array(),array('id' => 'asc', 'descripcion' => 'asc'));
Unrecognized field: id
$query=$em->getRepository('usuariosBundle:IPerfil')->createQueryBuilder('p')
->orderBy('id', 'ASC')
->getQuery();
$entities = $query->getResult();
*[Semantical Error] line 0, col 60 near 'id ASC': Error: 'id' is not defined. *
$entities = $this->get('doctrine')->getEntityManager()->createQuery('SELECT p.id FROM usuariosBundle:IPerfil p ')->getResult();
[Semantical Error] line 0, col 9 near 'id FROM usuariosBundle:IPerfil': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
Use attribute name of class, no column name on dql => 'id'
->orderBy('p.id', 'ASC') and ->createQuery('SELECT p FROM usuariosBundle:IPerfil p ')->getResult(), the name of bundle is usuarios os Usuarios ?
If it is useful to anyone, I finally created a non-persistent attribute in the Perfil entity to attach the the relationship and a collection of IPerfil's there:
/**
* #ORM\OneToMany(targetEntity="IPerfil", mappedBy="id")
*/
private $desc;
Need to declare it as a ArrayCollection:
public function __construct()
{
$this->desc = new \Doctrine\Common\Collections\ArrayCollection();
}
And now I'm able to lazy load in the right direction and do any necessary operation. I suppouse Doctrine couldnt load the collection into id, as it wasn't declared as a collection and it's the ID field.