createQueryBuilder with Join in Doctrine - symfony

If I do this:
->select('a')
->from('AppBundle:Accomodation', 'a')
->innerJoin('AppBundle:AccomodationRoom', 'ap', Join::WITH, $qb->expr()->eq('ap.accomodation', 'a.id'))
->getQuery()->getResult();
all the fields in Accomodation are selected.
But if I add this 'ap' to the select, as below, it doesn't select the Accomodation fields:
->select('a', 'ap')
->from('AppBundle:Accomodation', 'a')
->innerJoin('AppBundle:AccomodationRoom', 'ap', Join::WITH, $qb->expr()->eq('ap.accomodation', 'a.id'))
->getQuery()->getResult();
The relation between entities. This is Accomodation:
/**
* #ORM\OneToMany(targetEntity="AccomodationRoom", mappedBy="accomodation")
*/
private $rooms;
And this is AccomodationRoom:
/**
* #ORM\ManyToOne(targetEntity="Accomodation", inversedBy="rooms")
* #ORM\JoinColumn(name="accomodation_id", referencedColumnName="id")
*/
private $accomodation;
Please, any idea?

You have to select Accomodation and AccomodationRooms.
->select('a', 'ap')
->from('AppBundle:Accomodation', 'a')
->innerJoin('a.rooms', 'ap')
->getQuery()->getResult();

Related

Symfony 4 doctrine many to many with findby -> Column not found: 1054

I'm trying to make a many to many join with a Doctrine findBy()
$articles = $entityManager->getRepository(Articles::class)
->findBy(['rubriquesrubriques'=>$id],['idarticles'=>"ASC"]);
But I get
An exception occurred while executing
'SELECT t0.idarticles AS idarticles_1,
t0.thetitle AS thetitle_2, t0.theslug AS theslug_3, t0.thedescription AS
thedescription_4, t0.thedate AS thedate_5, t0.users_idusers AS users_idusers_6
FROM articles t0 WHERE
articles_has_rubriques.rubriques_idrubriques = ?
ORDER BY t0.idarticles ASC' with params ["2"]:
SQLSTATE[42S22]: Column not found: 1054 Champ
'articles_has_rubriques.rubriques_idrubriques' inconnu dans where clause
The column articles_has_rubriques.rubriques_idrubriques exists in my DB,
but I don't see the INNER JOIN !
When I make my many to many with a simple Find():
$articles = $entityManager->getRepository(Articles::class)->find($id);
The query is correct!
SELECT t0.idrubriques AS idrubriques_1,
t0.thertitle AS thertitle_2
FROM
rubriques t0
INNER JOIN articles_has_rubriques ON t0.idrubriques =
articles_has_rubriques.rubriques_idrubriques
WHERE articles_has_rubriques.articles_idarticles = ?
is it impossible to perform my many2many query with a findBy in the 4.1.6 version of Symfony???
This is my ORM relation:
In entity Rubriques.php:
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Articles", mappedBy="rubriquesrubriques")
*/
private $articlesarticles;
In entity Articles.php
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Rubriques", inversedBy="articlesarticles")
* #ORM\JoinTable(name="articles_has_rubriques",
* joinColumns={
* #ORM\JoinColumn(name="articles_idarticles", referencedColumnName="idarticles")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="rubriques_idrubriques", referencedColumnName="idrubriques")
* }
* )
*/
private $rubriquesrubriques;
Thank you so much
My question was stupid :
I'have an easy way to do that:
$rubriqueActu = $entityManager->getRepository(Rubriques::class)->find($id);
$articles = $rubriqueActu->getArticlesarticles();
SQL:
SELECT t0.idarticles AS idarticles_1, t0.thetitle AS thetitle_2,
t0.theslug AS theslug_3, t0.thedescription AS thedescription_4,
t0.thedate AS thedate_5, t0.users_idusers AS users_idusers_6
FROM articles t0 INNER JOIN articles_has_rubriques
ON t0.idarticles = articles_has_rubriques.articles_idarticles
WHERE articles_has_rubriques.rubriques_idrubriques = ?

how to set more than one condition in Doctrine ManyToMany

how to set more than one condition in doctrine ManyToMany ..
model
/**
* #ORM\ManyToMany(targetEntity="users",inversedBy="friends",cascade={"ALL"})
* #ORM\JoinTable(name="friends",
* joinColumns={#ORM\JoinColumn(name="friend_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")}
* )
*/
private $groupsa;
public function getusersre() {
return $this->groupsa;
}
output
SELECT
t0.id AS id_1,
t0.email AS email_2,
t0.username AS username_3,
t0.password AS password_4,
t0.first_name AS first_name_5,
t0.last_name AS last_name_6,
t0.location AS location_7,
t0.remember_token AS remember_token_8,
t0.created_at AS created_at_9,
t0.updated_at AS updated_at_10
FROM
users t0
INNER JOIN friends ON t0.id = friends.user_id
WHERE
friends.friend_id = ?
i want that it be like this
WHERE
friends.friend_id = ?
or friends.xxxx_id = ?
wait for a reponse , thanks for all ....
You can do as #SergioIvanuzzo suggests, but if you want to do this inside your entity you can also use the doctrine Doctrine\Common\Collections\Criteria class for this. You can read all about it in the documentation chapter 8.8. Filtering Collections.
public function getFriends(){
$id = 1; // ...the id you want to use for filtering
$criteria = Criteria::create()
->where(Criteria::expr()->eq("xxxx_id", $id));
return $this->friends->matching($criteria);
}

Query m:n relationship for n = null - returns Lexer error

Building a query to select M entities that have no corresponding N entities returns an error with the following query:
return $this->getEntityManager()
->createQuery(
'SELECT p FROM VolVolBundle:Opportunity p '
. 'LEFT JOIN VolVolBundle:Volunteer v'
. 'WHERE v.id is null '
. 'ORDER BY p.organization ASC'
);
returns the error:
Expected Doctrine\ORM\Query\Lexer::T_WITH, got 'v'
Yet the following SQL statement returns a non-empty resultset:
select o.id from opportunity o
left outer join opportunity_volunteer ov on o.id = ov.opportunity_id
left outer join volunteer v on ov.volunteer_id = v.id
where ov.id is null;
where opportunity_volunteer is the linking table
Opportunity entity relationship definition
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Volunteer", inversedBy="opportunities", cascade={"persist"})
* #ORM\JoinTable(name="opportunity_volunteer",
* joinColumns={#ORM\JoinColumn(name="opportunity_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="volunteer_id", referencedColumnName="id")}
* ))
*/
protected $volunteers;
public function addVolunteer(\Vol\VolBundle\Entity\Volunteer $volunteer) {
$volunteer->addOpportunity($this);
array_push($volunteers, $volunteer);
}
public function getVolunteers() {
return $this->volunteers;
}
Volunteer entity relationship definition
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="Opportunity", mappedBy="volunteers")
*/
protected $opportunities;
public function addOpportunity(\Vol\VolBundle\Entity\Opportunity $opportunity) {
array_push($opportunities, $opportunity);
}
public function getOpportunities() {
return $this->opportunities;
}
Reading from the DQL docs, you should use WITH instead of WHERE to limit the join. Search for the code snippet "Restricting a JOIN clause by additional conditions" in the docs. I guess it should be something like:
return $this->getEntityManager()
->createQuery(
'SELECT p FROM VolVolBundle:Opportunity p '
. 'LEFT JOIN VolVolBundle:Volunteer v'
. 'WITH v.id IS null '
. 'ORDER BY p.organization ASC'
);
This is not tested, though.
The eventual solution was to create a 1:n:1 relationship, eliminating the "invisible" entity in the middle. This enabled adding fields to the relationship. So in addition to assuring each line ended with a space character before concatenation the query needed to be rewritten. It now finds the null results as desired:
return $this->getEntityManager()
->createQuery(
'SELECT p FROM VolVolBundle:Opportunity p '
. 'LEFT JOIN VolVolBundle:OpportunityVolunteerEmail e '
. 'with p = e.opportunity '
. 'where e.opportunity is null'
. 'ORDER BY p.organization ASC'
)->getResult();

Doctrine 2. How can i get only one column from table?

I have this entity:
class TruckOrderPud {
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="Pud")
* #ORM\JoinColumn(name="pud_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $pudId;
/**
* #ORM\Id
* #ORM\OneToOne(targetEntity="TruckOrder")
* #ORM\JoinColumn(name="truck_order_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $truckOrderId;
/**
* #ORM\Column(name="package_count", type="integer", options={"unsigned"=true}, nullable=true)
*/
protected $packageCount;
/**
* #ORM\Column(name="package_weight", type="integer", options={"unsigned"=true}, nullable=true)
*/
protected $packageWeight;
}
I am needing get only single column pudId from this entity by truckOrderId parameter.
I am try:
$result = $this->_em->createQuery('SELECT top.pudId FROM AppTruckingBundle:TruckOrderPud top WHERE top.truckOrderId = ?1')
->setParameter(1, $truckOrderId)
->getSQL();`
Then I have error:
"[Semantical Error] line 0, col 11 near 'pudId FROM AppTruckingBundle:TruckOrderPud': Error: Invalid PathExpression. Must be a StateFieldPathExpression."
If i change query from 'SELECT top.pudId...' on 'SELECT top...' is it all OK.
I am also try:
$qb = $this->_em->createQueryBuilder();
$qb->select('top.pudId')
->from('AppTruckingBundle:TruckOrderPud', 'top')
->where($qb->expr()->eq('top.truckOrderId', $truckOrderId));`
In this case I am getting identical error. If i change $qb->select('top.pudId') on $qb->select('top') is it all OK.
Thanks for help!
PudId is a foreign key that refers to Pud, so you have to refer to Pud. Try this
$qb->select('IDENTITY(top.pud) PudId')
->from('AppTruckingBundle:TruckOrderPud', 'top')
->where($qb->expr()->eq('top.truckOrderId', $truckOrderId));`
Try to remove the 1 from the ?1 and leave only ?:
$result = $this->_em->createQuery('SELECT top.pudId FROM AppTruckingBundle:TruckOrderPud top WHERE top.truckOrderId = ?')
->setParameter(1, $truckOrderId)
->getSQL();
Doctrine does the parameter positioning by itself (first param on the first question mark spot). Read here for details.

doctrine 2 multiple join in one query give me error

I have query with two MtM relations:
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$qb
->select('o')
->from('UserBundle:User', 'o')
;
$qb->join('o.organisations', 'org')
->where('org.id = :organisation')
->setParameter('organisation', $filterData['organisation'])
;
$qb
->join('o.scientificDirections', 'd')
->where('d.id IN (:directionIds)')
->setParameter('directionIds', $directionIds)
->orderBy('o.surname')
;
return $qb->getQuery();
But it gives me error: Invalid parameter number: number of bound variables does not match number of tokens.
Can anybody explain me what is wrong?
Relation in User model:
/**
* #ORM\ManyToMany(targetEntity="\StrangeBundle\Entity\ScientificDirection")
*
*/
protected $scientificDirections;
/**
* #ORM\ManyToMany(targetEntity="\StrangeBundle\Entity\Organisation", mappedBy="workers")
*/
protected $organisations;
I think the reason is because you used where twice. That overwrites the first where, which is why it is giving you the parameters number error.
Use andWhere

Resources