I am trying to use native query in doctrine and for now created something really simple:
$rsm = new ResultSetMapping();
$rsm->addEntityResult('ObjectA', 'a');
$rsm->addFieldResult('a', 'id', 'id');
$query = $em->createNativeQuery('SELECT * FROM table a', $rsm);
What I try using this code, I am getting an error that ObjectA is not a valid entity or mapped super class. Which is totally true.
My question is: Is there any way to mad result of a native query to any arbitrary class (not Entity), but still user Doctrine's tools to do it.
Note: I am trying to avoid usage of lower level PDO.
Thank you.
Nothing like that, neither in the doc nor in the source code Doctrine\ORM\Query\ResultSetMapping (and it happens that some features are not documented).
I'd go with using scalar results and mapping the query result back to the object. Something like this:
$rsm = new ResultSetMapping();
$rsm->addScalarResult('a', 'a');
$rsm->addScalarResult('b', 'b');
$query = $em->createNativeQuery('SELECT a, b FROM table LIMIT 1', $rsm);
$result = $query->getSingleResult();
$a = new ObjectA();
$a->setA($result['a']);
// or
$a = new ObjectA($result); // with mapping passed to the constructor
Related
I am calling a stored procedure using native sql via doctrine. fetchAllAssociative() and execute are deprecated. What are the alternatives?
$sql = 'CALL spWithParams(:param)';
$stmt = $this->getEntityManager()->getConnection()->prepare($sql);
$stmt->execute([":param"=>"test"]);
print_r($stmt->fetchAllAssociative());
I am not planning to map the response to entity using ResultSetMapping() as mentioned here as I will add my custom wrapper on it.
The right way of doing this is to use a ResultSetMapping with scalar results to select arbitrary fields. You can then execute the query with getArrayResult() to achieve the same behaviour as in the provided code.
As an example:
$rsm = new ResultSetMapping();
$rsm->addScalarResult('my_database_column', 'myField');
$query = $this->getEntityManager()->createNativeQuery(
'CALL spWithParams(:param)',
$rsm
);
$query->setParameters([":param"=>"test"]);
$results = $query->getArrayResult();
/*
[
['myField' => 'foo'],
['myField' => 'bar']
]
*/
I have the following query that should check the start and end date in another entity and compare it against the start and end dates enter to create an instance of an entity, however its not returning anything.
public function createAction(Request $request)
{
$entity = new Payrollperiod();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$qb = $em->getRepository('comtwclagripayrollBundle:PayrollWeek')->createQueryBuilder('p');
$qb->select('p')
->where('p.startDate = :entityStart')
->andWhere('p.endDate = :entityEnd')
->setParameter('entityStart',$entity->getstartDate())
->setParameter('entityEnd',$entity->getendDate())
->getQuery()
->getResult();
How long I've been using Doctrine, I've never seen:
In MySQL (and PostgreSQL, SQLite) equal symbol is =, not ==.
In DQL you can't use entities' methods like getStartDate(), only attributes (in detail you can use only fields and associations defined in entity's mapping).
So:
$qb->select('p')
->where('p.getstartDate()==entity.startDate')
->andWhere('p.getendDate()==entity.endDate');
Should be:
$qb->select('p')
->where('p.startDate = entity.startDate')
->andWhere('p.getEndDate = entity.endDate')
What is entity.*? You have not declared entity Entity in your DQL.
[EDIT] If entity.* is another entity and you not define its in Query, then you must parameterize it:
$qb->select('p')
->where('p.startDate = :entityStart')
->andWhere('p.getEndDate = :entityEnd')
->setParameter('entityStart', $entity->getStartDate())
->setParameter('entityEnd', $entity->getEndDate())
Without exception message I cannot tell more about your code. It could be NonUniqueResultException because query finds more than 1 result.
Doctrine (and Symfony) have so many exceptions where everything is nice explain - what's crashed, why, where. Sometimes even the name of exception tell us everything - like UniqueConstraintViolationException.
I'm building a zend framework 2 application with php 5.6
I'm using doctrine2 for the database related code.
I created Yaml files for each table in the database.
I'm trying to call a query and return it's result.
I'm using the following code:
$query=<<<EOS
QUERY...
EOS;
$objectManager=$this->getObjectManager();
$rsm = new ResultSetMapping();
$rsm->addEntityResult( 'MyAlcoholist\Entity\DrinkFlavorInfo','u');
$rsm->addFieldResult('u','drink_type_name','drinkTypeName');
$rsm->addFieldResult('u','drink_brand_name','drinkBrandName');
$rsm->addFieldResult('u','drimk_company_name','drinkCompanyName');
$rsm->addFieldResult('u','drink_flavor_type_name','drinkFlavorTypeName');
$query = $objectManager->createNativeQuery($query,$rsm);
$query->setParameter(1, $id);
$drinkFlavors = $query->getResult();
die(var_export($drinkFlavors,1));
I created a class called DrinkFlavorInfo with getters and setters for the variables but since i configured doctrine to work with yaml then it's searching for a yaml file instead.
in yaml configuration one of the properties is table_name and there is no table, i'm just trying to create a class that will hold the returned values. how can i do so?
ok so it appears that this is how i should have defined the columns and execute the query:
$objectManager=$this->getObjectManager();
$rsm = new ResultSetMapping();
$rsm->addScalarResult('drink_brand_name','drinkBrandName');
$rsm->addScalarResult('drink_type_name','drinkTypeName');
$rsm->addScalarResult('drink_flavor_type_name','drinkFlavorTypeName');
$rsm->addScalarResult('drink_company_name','drinkCompanyName');
$query = $objectManager->createNativeQuery($query,$rsm);
$query->setParameter(1, $id);
$drinkFlavors = $query->getArrayResult();
die(var_export($drinkFlavors,1));
this works :)
I'm working with Entity objects from Doctrine queries and i end up with a very big array, with all information from all entities related. This ends up being a huge data tree... how can i limit this? Avoid listing all data from all relationships?
You can always remove not needed associations (this is a best practice for speeding up Doctrine). Or you can select only fields that you need in your presentation layer (as read-only data):
public function getAll()
{
$qb = $this->createQueryBuilder('u'); // Where are in User custom repository
return $qb
->select(array('u.id', 'u.first', 'u.last'))
->getQuery()
->getResult();
}
If you still need to work with objects (or for complex queries that needs plain SQL) a possibility is filling only needed properties (and eventually, associations/nested collections) of your domain object.
An example, more on native SQL:
public function getAll()
{
$mapping = new \Doctrine\ORM\Query\ResultSetMapping();
$mapping->addEntityResult('Acme\HelloBundle\User', 'e');
$mapping->addFieldResult('e', 'id', 'id');
$mapping->addFieldResult('e', 'first', 'first');
$mapping->addFieldResult('e', 'last', 'last');
$sql = "SELECT id, first, last FROM user ";
$result = $this->_em->createNativeQuery($sql, $mapping)->getResult();
// Or hust return $result itself (array)
return new \Doctrine\Common\Collections\ArrayCollection($result);
}
Of course the disadvance (?) is use of native SQL. I don't believe that ResultSetMapping can be used with DQL.
EDIT: take a look at http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/best-practices.html
$shops = $this->em->getRepository('models\Shop')->findAll();
Gives my an array with entities but I need the entity as array.
How do I convert an entity to an array?
Doctrine allows you to specify a hydration mode when executing queries, which let's you change the data type of the results returned. In this case, you need Query::HYDRATE_ARRAY. It does not let you specify this on the default findAll() method, found on the repositories. You will need to write your own DQL for it.
If you need a collection of entites as arrays:
$query = $em->createQuery('SELECT u FROM User u');
$entites = $query->execute(array(), Query::HYDRATE_ARRAY);
// If you don't have parameters in the query, you can use the getResult() shortcut
$query = $em->createQuery('SELECT u FROM User u');
$entities = $query->getResult(Query::HYDRATE_ARRAY);
If you need a single entity as an array, eg. for a specific ID:
$query = $em->createQuery('SELECT u FROM User u WHERE u.id = ?1');
$query->setParameter(1, $id);
$entity = $query->getSingleResult(Query::HYDRATE_ARRAY);
These methods are defined on Query, and AbstractQuery.
I had the same issue.return get_object_vars($this) is not a good solution because it also converts internal doctrine object/properties too.After some research i found this class: EntitySerializer which creates clean array or JSON from your entities and removes unnecessary items.The documentation is located here.For example i used the following code:
$patientProfile = $this->em->getRepository('Entities\Patientprofile')->findOneByuserid('2222222');
$entitySerializer=new Bgy\Doctrine\EntitySerializer($this->em);
$patientProfile=$entitySerializer->toArray($patientProfile);