I want create a multilingual web site, and for that I use Symfony with the PrezentBundle and A2lixBundle. I would get the list of my data by locale with entity repo.
I have this error :
FatalErrorException: Error: __clone method called on non-object in /project/vendor/doctrine/orm/lib/Doctrine/ORM/QueryBuilder.php line 238
Here is my repo :
$qb = $this->createQueryBuilder('c')
->leftJoin('c.criteres', 'crit')
->leftjoin('c.translations', 'ct', 'WITH', 'ct.locale = :locale')
->setParameters('locale', 'fr');
var_dump($qb->getDql() );
return $qb->getQuery()
->getResult();
The var_dump give me that :
SELECT c FROM NS\MyBundle\Entity\CritereCateg c LEFT JOIN c.criteres crit LEFT JOIN c.translations ct WITH ct.locale = :locale
Your issue is probably because of misuse of the setParameters() mehtod. There is two simmilar methods for the doctrine query builder:
1) setParameter() which sets only one parameter per method usage. The syntax is:
// for numeric parameters
$qb->leftjoin('c.translations', 'ct', 'WITH', 'ct.locale = ?1')
->setParameter(1, 'fr');
// for string parameters
$qb->leftjoin('c.translations', 'ct', 'WITH', 'ct.locale = :locale')
->setParameter('locale', 'fr');
2) setParameters() which sets multiple parameters:
// String params
$qb->where('u.id = :uid')
->leftjoin('c.translations', 'ct', 'WITH', 'ct.locale = :locale')
->setParameters(array('locale' => 'fr', 'uid' => $userId));
// Numeric parameters are also available here
$qb->where('u.id = ?1')
->leftjoin('c.translations', 'ct', 'WITH', 'ct.locale = ?2')
->setParameters(array(2 => 'fr', 1 => $userId));
So you probably wanted to use setParameter() instead of setParameters() in your query builder.
Related
I have two mysql tables and corresponding entities:
Question
--------
id
text
level
Asked
--------
* #ORM\ManyToOne(targetEntity="QuestionEntity")
* #ORM\JoinColumn(name="question", referencedColumnName="id")
question
user
I want to query for all questions that has a specific level and the question haven't been asked from a given user. How can I do this with an entity manager query builder?
With MySQL syntax the query would be:
SELECT
*
FROM
Question
WHERE
Question.level = 1
AND Question.id NOT IN( SELECT Asked.question FROM Asked WHERE Asked.user = 23)
I tried multiple things like Tomasz Madeyski commented, but I still got 500 Internal Server Error. This is my code: (I tested the subquery and it was fine when it is stand alone)
$em = $this->getDoctrine()->getManager();
$fbUser = $em->getRepository(FbUserEntity::class)->findOneBy(['fbId' => $session->get('fb_user_id')]);
$qb = $em->createQueryBuilder();
$qb2 = $qb;
$questions = $qb->select('q')
->from('MyBundle:QuestionEntity', 'q')
->where('q.level = :level')
->setParameter('level', $level)
->andWhere($qb->expr()->notIn(
'q.id',
$qb2->select('a.question')
->from('LMyBundle:AskedEntity', 'a')
->where('a.user = :userid')
->setParameter('userid', $fbUser->getId())
->getDQL()
))
->getQuery()
->getResult();
Try something like this:
$qb = $em->createQueryBuilder();
$subQuery = $qb->select('a.question')
->from('YourBundle:Asked', 'a')
->andWhere('a.user = 23')
$query = $qb->select('q')
->from('YourBundle:Question', 'q')
->andWhere('q.level = 1')
->andWhere($qb->expr()->notIn('q.id', $subQuery->getDQL())
->getQuery()
->getResult()
The key here is $qb->expr()->notIn() part
Investigating the logs I figured out that instead of
$qb = $em->createQueryBuilder();
$qb2 = $qb;
I should create a new queryBuilder for qb2:
$qb = $em->createQueryBuilder();
$qb2 = $em->createQueryBuilder();
But this still gives me an error. After some experimentingI figured out that if the subquery is executed, it gives something like this format:
array (size=2)
0 =>
array (size=1)
'question' => int 1
1 =>
array (size=1)
'question' => int 2
So I run through the subquery result like this:
$alreadyAsked = [];
foreach($asked as $q){
$alreadyAsked[] = $q['question'];
}
And pass the $alreadyAsked array to the main query like this, then it works:
->andWhere($qb->expr()->notIn('q.id', $alreadyAsked))
I have 2 non related entities: External and Internal. I need to union select all results from entities. I am using ResultSetMapping and Native SQL to do this:
$em = $this->getDoctrine()
->getManager()->getConnection();
$rsm = new \Doctrine\ORM\Query\ResultSetMapping();
$rsm->addEntityResult('ExternalBundle:External', 'e');
$rsm->addFieldResult('e', 'id', 'id');
$rsm->addFieldResult('e', 'status', 'status');
$rsm->addFieldResult('e', 'name', 'name');
$rsm->addEntityResult('InternalBundle:Internal', 'i');
$rsm->addFieldResult('i', 'id', 'id');
$rsm->addFieldResult('i', 'status', 'status');
$rsm->addFieldResult('i', 'name', 'name');
$sql = "SELECT e.*
FROM external_print e
UNION
SELECT i.*
FROM internal_print i";
$objects = $this->$em->createNativeQuery($sql, $rsm)->getResult();
I keep getting this error: Catchable Fatal Error: Object of class Doctrine\ORM\EntityManager could not be converted to string.
What needs to be fixed?
You have a code error instead of
$objects = $this->$em->createNativeQuery($sql, $rsm)->getResult();
use just
$objects = $em->createNativeQuery($sql, $rsm)->getResult();
I am trying to order results of my query by day and month, here is my code
public function getUserBirthday($idList)
{
$queryBuilder = $this->_em->createQueryBuilder();
$queryBuilder->select('fb')
->from('Wishwish\ApplicationBundle\Entity\FbUser', 'fb')
->where(' Week(fb.birthday)<= Week(:now)+2')
->andWhere('Week(fb.birthday)> Week(:now)')
->andWhere('fb.id IN (:idList)')
->orderBy('DAY(fb.birthday)')
->addOrderBy('MONTH(fb.birthday)');
$queryBuilder->setParameter('now', new \DateTime());
$queryBuilder->setParameter('idList',$idList);
return $queryBuilder->getQuery()->getResult();
}
this id the error displayed :
[Syntax Error] line 0, col 170: Error: Expected end of string, got '('
500 Internal Server Error - QueryException
1 linked Exception: QueryException ยป
update =>solution :
the trick was to use createNativeQuery
public function getUserBirthday($idList)
{
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Wishwish\ApplicationBundle\Entity\FbUser', 'fb');
$rsm->addFieldResult('fb', 'birthday', 'birthday');
$rsm->addFieldResult('fb', 'picture', 'picture');
$rsm->addFieldResult('fb', 'name', 'name');
$rsm->addFieldResult('fb', 'id', 'id');
$sql ='select * from fb_user
where (Week(birthday)<= Week(:now)+2) and (Week(birthday)> Week(:now))
and (id IN (:idList)) ORDER By DAY (birthday),MONTH (birthday)';
$query = $this->_em->createNativeQuery($sql, $rsm);
$query->setParameter('now', new \DateTime());
$query->setParameter('idList',$idList);
return $query->getResult();
}
Try to use createNativeQuery() method for more complex query:
use Doctrine\ORM\Query\ResultSetMapping;
$rsm = new ResultSetMapping();
$query = $this->_em->createNativeQuery('
SELECT fb
FROM WishwishApplicationBundle:FbUser fb
WHERE Week(fb.birthday) <= Week(:now)+2
AND Week(fb.birthday) > Week(:now)
AND fb.id IN (:idList)
ORDER BY DAY(fb.birthday) ASC, MONTH(fb.birthday) ASC
', $rsm)
->setParameter('now', new \DateTime())
->setParameter('idList',$idList);
$result = $query->getResult();
when I run a query with date in where clause, following error is showed...
[Syntax Error] line 0, col 129: Error: Expected known function, got 'DATE_FORMAT'
the query is given below
$query = $this->getEntityManager()->createQuery(
"SELECT a.id, a.amont, a.paymentDescrip, a.paymentType, a.paymentDate
FROM RegalSmsBundle:DailyTransaction a
WHERE DATE_FORMAT(a.paymentDate,'%Y-%m-%d') = :paymentDate
and a.students = :studentId"
)->setParameter('studentId', $studentId)
->setParameter('paymentDate','2013-03-11');
return $query->getResult();
Doctrine doesn't have DATE_FORMAT function defined by default. It's possible to Register Custom DQL Function.
But you can compare date easily (assuming a.paymentDate is of type date):
$query = $this->getEntityManager()->createQuery("
SELECT a.id, a.amont, a.paymentDescrip, a.paymentType, a.paymentDate
FROM RegalSmsBundle:DailyTransaction a
WHERE a.paymentDate = :paymentDate AND a.students = :studentId
")
->setParameter('studentId', $studentId)
->setParameter('paymentDate', new \DateTime('2013-03-11'))
;
return $query->getResult();
Edit: I prefer using querybuider to writing DQL. It would look like this:
$qb = $this->getEntityManager()->getRepository('RegalSmsBundle:DailyTransaction')->createQueryBuilder('a');
$qb
->select('a') // select whole entity
->where($qb->expr()->andX(
$qb->expr()->eq('a.paymentDate', ':paymentDate')
$qb->expr()->eq('a.students', ':studentId')
))
->setParameter('studentId', $studentId)
->setParameter('paymentDate', new \DateTime('2013-03-11'))
;
return $qb->getQuery()->getResult();
Im trying to reproduce this query:
SELECT * FROM `request_lines`
where request_id not in(
select requestLine_id from `asset_request_lines` where asset_id = 1
)
in doctrine query builder,
I am stuck on the where request_id not in(select
I currently have:
$linked = $em->createQueryBuilder()
->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where()
->getQuery()
->getResult();
You need to use query builder expressions, and this means you need access to the query builder object. Also, the code is easier to write if you generate the subselect list ahead of time:
$qb = $em->createQueryBuilder();
$nots = $qb->select('arl')
->from('$MineMyBundle:MineAssetRequestLine', 'arl')
->where($qb->expr()->eq('arl.asset_id',1))
->getQuery()
->getResult();
$linked = $qb->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where($qb->expr()->notIn('rl.request_id', $nots))
->getQuery()
->getResult();
It is possible to do this in one Doctrine query:
$qb = $this->_em->createQueryBuilder();
$sub = $qb;
$sub = $qb->select('arl')
->from('$MineMyBundle:MineAssetRequestLine', 'arl')
->where($qb->expr()->eq('arl.asset_id',1));
$linked = $qb->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where($qb->expr()->notIn('rl.request_id', $sub->getDQL()))
->getQuery()
->getResult();
Check the reference in this answer here
Using Symfony 5, this solution might help those, who are trying to set parameters on a subquery, the notIn() 2nd argument accepts an array or you could pass a DQL instead and that's what we are doing here and keep in mind that the parameters should be added to the main query as below.
$main = $this->em->createQueryBuilder();
$sub = $main;
$sub = $sub->select('arl')
->from('$MineMyBundle:MineAssetRequestLine', 'arl')
->where($sub->expr()->eq('arl.asset_id',':id'));
$linked = $main->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where($main->expr()->notIn('rl.request_id', $sub->getDQL()))
->setParameter('id', 1)
->getQuery()
->getResult();