I'm encountering a challenging issue with a Doctrine ORM query related to finding user contacts based on my Account and Contact entities. Let me provide some context:
Entity Structure:
Contact Entity:
/**
* @ORM\ManyToOne(targetEntity=Account::class, inversedBy="contacts")
* @ORM\JoinColumn(nullable=false)
*/
private $Account_source;
/**
* @ORM\ManyToOne(targetEntity=Account::class, inversedBy="contacts_backward")
* @ORM\JoinColumn(nullable=false)
*/
private $Account_Targets;
Account Entity:
/**
* @ORM\OneToMany(targetEntity=Contact::class, mappedBy="Account_source", orphanRemoval=true)
*/
private $contacts;
/**
* @ORM\OneToMany(targetEntity=Contact::class, mappedBy="Account_Targets", orphanRemoval=true)
*/
private $contacts_backward;
Issue Description:
I'm trying to write a Doctrine ORM query that allows me to find user contacts for a given user ($searcherId), where that user can be either the Account_source or the Account_Targets in the contact relationship. The goal is to find contacts in both directions of the relationship.
The Initial Query:
Initially, I wrote the following query, which only found contacts in one direction of the relationship, where the logged in user was the Account_Target:
public function searchByName($value, $searcherId)
{
return $this->createQueryBuilder('a')
->select('a.firstName as firstname', 'a.lastName as lastname', 'a.username as username', 'a.id as id')
->leftJoin('a.contacts', 'c')
->where('c.Account_source = :id AND a.id = c.Account_Targets')
->andWhere('(a.username like :val OR a.firstName like :val OR a.lastName like :val)')
->setParameter('val', '%' . $value . '%')
->setParameter('id', $searcherId)
->orderBy('a.firstName', 'ASC')
->getQuery()
->getResult();
}
The Problem:
The initial query worked for finding contacts in one direction where the user logged in was the Account_Target. However, it didn't cover the scenario where the user logged in could also be the Account_source.
For example, Ostwind(targets) can find Skorpiono(source) but Skorpiono(source) also can only find Skorpiono(source)
Attempted Solution:
To address this limitation, I modified the query to include both directions of the relationship, as follows:
// The modified query that attempted to find contacts in both directions
public function searchByName($value, $searcherId)
{
return $this->createQueryBuilder('a')
->select('a.firstName as firstname', 'a.lastName as lastname', 'a.username as username', 'a.id as id')
->leftJoin('a.contacts', 'c')
->leftJoin('a.contacts_backward', 'cb')
->where('(c.Account_source = :id AND a.id = c.Account_Targets) OR (cb.Account_Targets = :id AND a.id = cb.Account_source)')
->andWhere('(a.username like :val OR a.firstName like :val OR a.lastName like :val)')
->setParameter('val', '%' . $value . '%')
->setParameter('id', $searcherId)
->orderBy('a.firstName', 'ASC')
->getQuery()
->getResult();
}
The Current Issue:
Now, the current issue is that the modified query doesn't return any results, and I'm unable to find contacts in either direction of the relationship.
I found answer, it was UNION