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

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 = ?

Related

How to create constraint for limiting max childs

Let's say I have two entities Bus and People with a relation OneToMany between them.
Bus can hold a maximum of 10 persons.
How to create a constraint to control this?
For example:
* #MyAssert\ParentMaxChild(max=10)
* #ORM\ManyToOne(targetEntity="Webface\CharacterBundle\Entity\Bus", inversedBy="wac")
* #ORM\JoinColumn(name="bus_id", referencedColumnName="id", nullable=false)
private $bus;
Use the Count constraint.
In your Bus class, add the constraint in the Person annotation:
/**
* ... Rest of the annotation ...
* #Assert\Count(
* max = "10",
* maxMessage = "Bus can hold a maximum of 10 persons."
* )
*/
protected $persons;
Note that you can specify a min parameter and the according message.

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.

How to map connection between three tables

I have three tables:
game columns: id | name (eg. 1 | Halo)
own columns: id | type_id | type_name (eg. 1 | 1 | on wishlist)
user columns: id | name (eg. 1 | Tomek)
Now what I have is a ManyToMany connection between those tables:
User (table user_own)
/**
* #ORM\ManyToMany(targetEntity="Own")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
Own (table own_game)
/**
* #ORM\ManyToMany(targetEntity="Game")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="game_id", referencedColumnName="id")}
* )
*/
My query:
public function getOwned() {
return $this->getEntityManager()
->createQuery('
SELECT u, o, g FROM AcmeGoBundle:User u
JOIN u.owners o
JOIN u.games g
')
->getResult();
}
I can retrieve games owned by particular user, but I can't connect type of ownership. How can I do this?
To crate ManyToMany with additional column with some data you need to create this by hand.
Doctrine ManyToMany relation crates a join table with id's of joined entities. So you need to create by your own Entity named ex. UserOwns with OneToMany relation to User and another OneToMany relation Own. Then you can add additional field with your data inside.
Check that question: Doctrine2: Best way to handle many-to-many with extra columns in reference table

Resources