Symfony2 Query with complex SQL in Repository - symfony

Bit of background first: we have a well evolved solution using Symfony1 and Propel which need to be migrated forward in time so I'm investigating migrating it to Symfony2.8 (with Doctrine).
I've not found a solution yet to having some SQL running it and then "hydrating" the results to object(s).
Any ideas.
Essentially I want to be able to do
$em = $this->getDoctrine()->getEntityManager();
$conn = $em->getConnection();
$sql = "SELECT xxxx";
$stmt = $conn->prepare($sql);
$stmt->bindValue(1, $siteId);
$rs = $stmt->execute();
$icount=0;
while ($rs->getnext())
{
$entity[$icount] = new Entity();
$entity[$icount] = hydrate($rs);
$icount++;
}
(those knowing propel will recognise this)
And I do get that if there is more than one entity in the query this should be in a service class of some kind.

I'd look into native SQL queries in doctrine. You can run regular SQL queries and get them hydrated into doctrine objects, with a little extra work.
Documentation here

Related

CreateQueryBuilder on an association table that has no entity

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

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.

Symfony2 Doctrine2 native queries basics

I am developing a basic web-app in my job. I have to work with some sql server views. I made the decision of trying native queries, and once tested it's functionality, try to write some classes to code all the queries and kinda forget their implementation.
So my issue is, I've got an Entity in Acme/MyBundle/Entity/View1.php.
This entity has got all the attributes matching the table and also it's getters and setters.
I guess this entity is well mapped to the DB (Doctrine cant work with views easily).
My aim is to let a Controller be able to fetch some data from those views(SQL SERVER) and return it to the view (twig) so it can display the info.
$returned_atts = array(
"att1" => $result[0]->getAttribute1(), //getter from the entity
"att2" => $result[1]->getAttribute2(), //getter from the entity
);
return $returned_atts;`$sql = "SELECT [Attribute1],[Attribute2],[Attribute3] FROM [TEST].[dbo].[TEST_VIEW1]"; //THIS IS THE SQL SERVER QUERY
$rsm = new ResultSetMapping($em); //result set mappin object
$rsm->addEntityResult('Acme\MyBundle\Entity\View1', 'view1'); //entity which is based on
$rsm->addFieldResult('view1', 'Attribute1', 'attribute1'); //only choose these 3 attributes among the whole available
$rsm->addFieldResult('view1', 'Attribute2', 'attribute2');
$rsm->addFieldResult('view1', 'Attribute3', 'attribute3');
//rsm built
$query = $em->createNativeQuery($sql, $rsm); //execute the query
$result = $query->getResult(); //get the array
It should be possible to return the array straight from the getResult() method isn't it?
And what's killing me, how can I access the attribute1, attriute2 and attriute2?
$returned_atts = array(
"att1" => $result[0]->getAttribute1(), //getter from the entity
"att2" => $result[1]->getAttribute2(), //getter from the entity
);
return $returned_atts;`
If you want result as array, you don't need to use ResultSetMapping.
$sql = " SELECT * FROM some_table";
$stmt = $this->getDoctrine()->getEntityManager()->getConnection()->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();
That is a basic example for controller action. You can dump the result, use var_dump(), to see how to access your particular field values.
More examples here Doctrine raw sql

Doctrine Querybuilder issues in symfony2. Usage questions

Using doctrine for the first time in a project, and I'm having a few issues with the query builder.
First up, in a controller I used the following:
$conn = $this->get('database_connection');
$users = $conn->fetchAll('SELECT * FROM Users');
This worked fine and returns an array of users from my DB.
I then tried to use the query builder to fetch the forenames of all users. By looking at examples i found the following:
$conn = $this->get('database_connection');
$qb = $conn->createQueryBuilder();
$qb->select("forename")
->from("Users", "u")
->where("u.id = :user_id")
->setParameter('user_id', 1);
$query = $qb->getQuery();
$results = $query->getResults();
I get told that the gDoctrine\DBAL\Query\QueryBuilder::getQuery() method is not defined, which I found odd as almost all the examples I found use it.
I did a search and found Doctrine documentation but I'm now confused how to use it at all.
Would someone be kind enough to give me an example of how to use the above to retrieve the forename for the User with id 1. I'm sure that once I have a simple example that work I will be fine from there.
Thanks!
Now Resolved:
After looking at the Documentation (and with help from others), I found the general layout for the queryBuilder is as follows:
$conn = $this->get('database_connection');
$qb = $conn->createQueryBuilder();
$stmt = $qb->select("forename")
->from("Users", "u")
->where("u.id = :user_id")
->setParameter('user_id', 1)
->execute();
$userNames = $stmt->fetchAll();
The general idea being that the execute method returns a Doctrine\DBAL\Driver\Statement, with the parameters set as specified. From this statement you can call one of the various method stated here to get the results from the DB.
Hope this helps someone else who is having problems!
I think you might be confused slightly by the documents on doctrine and using it with symfony. From the error message you are getting a DBAL\Query\QueryBuilder. There is not a method getQuery for that object. You should be able to use the execute method to get the results you want.
Now with that being said the way I would do it is through either a repository class for the Users entity, or I would do
$em = $this->get('doctrine.orm.entity_manager');
$qb = $em->createQueryBuilder();
then do what you were doing before...

Resources