CreateQueryBuilder on an association table that has no entity - symfony

I have an association table, that has no entity itself, inside an entity. I can do a raw or native query on it but I want to use createQueryBuilder on it. How can I?
Here is the raw query that I want to convert to createQueryBuilder:
$sql = 'SELECT t.* FROM tasks t LEFT JOIN question_tasks qt ON t.id = qt.task_id WHERE qt.question_id = :qtId';
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata(Task::class, 't');
$query = $this->_em->createNativeQuery($sql, $rsm);
$query->setParameter('qtId', $questionId);
return $query->getResult();
Thank you.

It's kind of impossible use Doctrine ORM without entity. QueryBuilder just converts down to DQL. DQL make queries over your object model.
Says documentation
You need to think about DQL as a query language for your object model,
not for your relational schema.
Check docs here Doctrine Query Language

Related

Doctrine Query reverse join?

I have these relations.
I need to retrieve all contents but order by star.content_Idcontent first.
It works with easy SQL:
SELECT content.idcontent
FROM content
LEFT JOIN star ON content.idcontent = star.content_Idcontent
ORDER BY star.content_Idcontent DESC,content.idcontent
But I don't know how to do it with Doctrine because content is not the owner of the relation.
Must I create a bidirectional relation or is there a way to make it work?
You can create a query in ContentRepository like:
$qb = $this
->createQueryBuilder('content')
->join(
'App\Entity\Star',
'star',
\Doctrine\ORM\Query\Expr\LeftJoin::WITH,
'content.idcontent = star.content_Idcontent '
)
->orderBy('star.content_Idcontent', 'DESC')
;
$qb->getResult();
Assuming that your Entity Star is located in App\Entity\Star

Doctrine duplicating query results?

I have the following code
$this->em = $this->container->get('doctrine.orm.entity_manager');
$qb = $this->em->getRepository('CoreBundle:ServiceProvider')->createQueryBuilder('c');
$qb->select('count(venue.id) as vencount');
$qb->from('CoreBundle:ServiceProvider','venue');
$count = $qb->getQuery()->getOneOrNullResult()['vencount'];
which is write its returning a number of venues but the problem is that this number is mistaken because in the ServiceProvider table i have only 5 records but this query is returning 25. I tried to add a new record so they are 6 and yes the result was 36.
So I added group by the id and it fixed the issue anyone can tell me why is this happening ?
It's because when you create a query from a repository Doctrine assumes its a select and inject the select and from clausule's for you.
This is the sql you get from using the getRepository method:
SELECT count(i0_.id) AS sclr_0 FROM Entity i1_, Entity i0_
(Note that the entity is twice in the FROM).
Using just:
$qb = $this->em->createQueryBuilder();
$qb->select('count(venue.id) as vencount');
$qb->from('CoreBundle:ServiceProvider','venue');
You get:
SELECT count(i0_.id) AS sclr_0 FROM Entity i0_
Which is probably what you are looking for.
Another alternative is to get it from the repository but clear the sql parts with:
$qb = $this->em->getRepository('CoreBundle:ServiceProvider')->createQueryBuilder('c')->resetDQLParts();
But this way you lost the very purpose of using the repository in the first place.

Doctrine joined inheritance, disable with queryBuilder

I have defined an entity as:
#ORM\InheritanceType("JOINED")
Which works fine.
When trying to execute a simple query as:
$_builder = $this->_em->createQueryBuilder();
$_builder->select('COUNT(us.id)')
->from('TbBundle:UserStatus', 'us')
->where('us.user = :user')
->setParameter('user', $user);
return $_builder->getQuery()->getSingleScalarResult();
Doctrine will produce a query with some unnecessary left joins due to my inheritance architecture. Can I disable it for this query with queryBuilder in any way?
The goal:
I want to build count query using query builder but execute it without any inheritance influence so the executed query is as simple as:
SELECT COUNT(us.id) FROM table_name us WHERE us.user_id = 34;
I could write it using raw sql and get connection from entityManager but that's ugly.

Doctrine DQL Delete from relation table

Using Doctrine 2 and Symfony 2.0.
I have two Doctrine entities (let's suppose EntityA and EntityB).
I have a ManyToMany relation between them. So a EntityA_EntityB table has been created in database.
Using DQL or QueryBuilder, how can I delete from that relation table EntityA_EntityB?
Docrtine offers something like this to perform something similar:
->delete()
->from('EntityA a')
->where('a.id', '?', $id);
But I don't really get how to perform the deletion of row from the relation table.
$em = ...; // instance of `EntityManager`
// fetch both objects if ID is known
$a = $em->getRepository("YourProjectNamespace:EntityA")->find($id_of_A);
$b = $em->getRepository("YourProjectNamespace:EntityB")->find($id_of_B);
// suppose you have `EntityA::getObjectsOfTypeB` which retrieves all of linked objects of type `EntityB`.
// This method return instacne of ArrayCollection
$a->getObjectsOfTypeB()->removeElement($b);
$em->flush();
Something like this?
Basically, you need to remove related object from collection rather than delete relation itself. you want to remove relation directly you can always use pure SQL, but in DQL that is not possible.
Raw DELETE SQL statement via DBAL Connection object
$conn = $this->getDoctrine()->getManager()->getConnection();
$stmt = $conn->prepare("DELETE FROM EntityAEntityB WHERE id_b IN (:ids_of_b)");
$stmt->bindParam('ids_of_b', $to_delete_ids); // BEWARE: this array has to have at least one element
$stmt->executeUpdate();

Is there possible to use createQueryBuilder for insert/update? If not, what function should I use?

For now I succeded to create a function that retrieves data from the database using Doctrine's function createQueryBuilder.
Does anybody know if there is a similar function to insert or update the database? Or how can i use createQueryBuilder?
Doctrine 2 ORM does not support INSERT via DQL or the DQL query builder. For a complete syntax, check the EBNF of DQL.
To handle inserts in ORM, you always manually instantiate an entity and persist it with the entity manager:
$user = new \My\Entity\User();
$entityManager->persist($user);
$entityManager->flush();
You can only handle SELECT, UPDATE and DELETE via DQL in Doctrine ORM:
Select:
SELECT u FROM My\Entity\User u WHERE u.id = :userId
Update:
UPDATE My\Entity\User u SET u.status = 'banned' WHERE u.id = :userId
Delete
DELETE My\Entity\User u WHERE u.id = :userId
You can handle these operations with the QueryBuilder as well:
Select:
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder
->select('u')
->from('My\Entity\User', 'u')
->where($queryBuilder->expr()->eq('u.id', ':userId'));
Delete:
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder
->delete('My\Entity\User', 'u')
->where($queryBuilder->expr()->eq('u.id', ':userId'));
Update:
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder
->update('My\Entity\User', 'u')
->set('u.status', 'banned')
->where($queryBuilder->expr()->eq('u.id', ':userId'));
Another option you have instead using a QueryBuilder, is using Doctrine DBAL prepare and execute functions. Probably is not as flexible as use QueryBuilder, but for do INSERTs in some situations could be useful.
The way to use is getting the Database Connection from the Entity Manager.
$sql = "INSERT INTO table (field1, field2) VALUES ('foo', 'var')";
$stmt = $em->getConnection()->prepare($sql);
$stmt->bindValue(':invoice', $invoiceId);
$result = $stmt->execute();
If you use DBAL queryBuilder, it is possible to insert.
$qb = $connection->createQueryBuilder();
To insert with the queryBuilder it is like this :
$qb->insert('MuBundle:MyClass', 'momc')
->values (array(
'property1 (id for example)' => '?'
'property2 (name for exmaple)' => '?'
))
->setParameter(0, $id)
->setparameter(1, $name)
using QueryBuilder to insert data is not possible unless your are willing to write the DQL or SQL. If you are looking for a way to simply insert data to your database table, you have to first of all make sure the data is loaded into an Entity class for the table in which you want to insert your data. For example $em->persist($entity);

Resources