Cascading hydrate with DoctrineHydrator - doctrine-orm

Is it possible?
$hydrator = $this->getServiceLocator()->get('DoctrineHydrator');
$hydrator->hydrate((array) $data, $PlatformEntity);
Hydrator hydrate only 1 level of array.

Array hydration is not the best way for achieve this kind of situations. The same scenario here:
Person
- id_person
- name
- child //self refering
Array hydration only select the first level. I resolving it taking one of these two options:
Use left join association
$query = $entityManager->createQueryBuilder()
->select('p1, p2, p3, p4, p5, p6')
->from('Entity\Person', 'p1')
->leftJoin('p1.child', 'p2')
->leftJoin('p2.child', 'p3')
->leftJoin('p3.child', 'p4')
->leftJoin('p4.child', 'p5')
->leftJoin('p5.child', 'p6')
->createQuery();
and then, use array hydration.
Create your own recursive function in order to add manually each element in an array.

Related

Efficient traversing of vector of vectors and reverse mapping for faster lookup

I have a function that returns a vector of vectors. I need to unravel and store it in a container like unordered_map so that lookup is faster.
vector<ssc> SSC = getSsc();
For each element from getSsc() say sid is another vector of ids say cid. They can look something like this:
SSC = [s1, s2, s3, s4] and each element of SCC be like:
s1 = [c1, c2, c3, c4]
s2 = [c5, c6]
s3 = [c7]
I need to look up for cid so that it returns s2 if I query for c5 or c6. I can do two for loops and populate an unordered_map container. But is there an efficient way to do this?
c1, .... n and s1, .... n are unique ids. But different cid can have same sid.
Used the nested for loop to solve the problem. As there will be a performance bottleneck, I used the tbb::parallel_for to do this operation. The nested loop runs pretty fast.

Merge 2 object lists in java

i have two lists listA and listB of type object
ListA[name=abc, age=34, weight=0, height=0] data collected from excel sheet
ListB[name=null, age=0, weight=70, height=6] data collected from database
Now i want to combine both the lists into a single list
MergedList[name=abc, age=34, weight=70, height=6]
Note: my obj class has more than 15 properties so adding each property one by one using getProperty() will be time-consuming.is there a better way?
Convert them to a Map where the key is the name of the object ( you denoting the elements as name=abc suggests they are name/value pairs ).
Map<String,MyMysteriousObject> converted = list.stream().collect( Collectors.toMap(MyMysteriousObject::getName, Function.identity() ) );
( replace the getName with what ever function you use to get the name of your object )
And then just merge the maps. How to merge maps is described here for example.
While at it, consider replacing the List with Map in your entire code. Will surely save a lot of work elsewhere too.
But if you have to have a list again, just List<MyMysteriousObject> resultList = new ArrayList<>(resultMap);

Flutter; Sort List of Widgets

I currently have a list of widgets
List<LessonItem> _lessons = [];
One Widget inside this list, added by the user should look like this
LessonItem('Bio', 'Mrs Pithan', 'A1.012', HourMinute('08', '00'),
HourMinute('11', '50'), Colors.green), //lesson, teacher, room, from, to, color
Now I want to sort the list by a specific property from the widgets. How can I do that?
Thanks for any help!
I would try with the sort method in dart.
You choose a property you want to sort by, and then define how any two elements will be compared.
Here I'm comparing each element by id (smaller id would en up first after sort):
_lessons.sort((LessonItem a, LessonItem b) => a.id - b.id);
In this case I'm sorting by name (with the compareTo() method from String):
_lessons.sort((LessonItem a, LessonItem b) => a.name.compareTo(b.name));
You can find more detailed info and some examples in:
dart documentation
and
this helpful post

doctrine 2 query if product equals to multiple categories

$categories= array(3,20,24);
$qb = $this->em->createQueryBuilder();
$qb->select('p')
->from('\Entities\Productss', 'p')
->leftJoin('p.category', 'c')
->andWhere('p.id =?1')
->andWhere('p.id =?2')
->andWhere('p.id =?2')
->setParameter(1, $categories[0])
->setParameter(2, $categories[1])
->setParameter(3, $categories[2])
->getQuery();
this doesnt allow multiple wheres...
$categories is an array which consist of categories it must match in order to select correct products. such as shoes(3), black(20), small(24)
possible?
In the documentation of Doctrine I found this:
// Example - $qb->expr()->in('u.id', array(1, 2, 3))
// Make sure that you do NOT use something similar to $qb->expr()->in('value', array('stringvalue')) as this will cause Doctrine to throw an Exception.
// Instead, use $qb->expr()->in('value', array('?1')) and bind your parameter to ?1 (see section above)
public function in($x, $y); // Returns Expr\Func instance
// Example - $qb->expr()->notIn('u.id', '2')
public function notIn($x, $y); // Returns Expr\Func instance
It should be possible to put a subquery in this function. I never used it myself, but give it a try.
EDIT
I understand it is a many-to-many relation. In this case you should use the MEMBER OF option.
So like:
$qb->...
->andWhere("p.category MEMBER OF ?1")
->andWhere("p.category MEMBER OF ?2")
->...

Getting odd behavior from $query->setMaxResults()

When I call setMaxResults on a query, it seems to want to treat the max number as "2", no matter what it's actual value is.
function findMostRecentByOwnerUser(\Entities\User $user, $limit)
{
echo "2: $limit<br>";
$query = $this->getEntityManager()->createQuery('
SELECT t
FROM Entities\Thread t
JOIN t.messages m
JOIN t.group g
WHERE
g.ownerUser = :owner_user
ORDER BY m.timestamp DESC
');
$query->setParameter("owner_user", $user);
$query->setMaxResults(4);
echo $query->getSQL()."<br>";
$results = $query->getResult();
echo "3: ".count($results);
return $results;
}
When I comment out the setMaxResults line, I get 6 results. When I leave it in, I get the 2 most recent results. When I run the generated SQL code in phpMyAdmin, I get the 4 most recent results. The generated SQL, for reference, is:
SELECT <lots of columns, all from t0_>
FROM Thread t0_
INNER JOIN Message m1_ ON t0_.id = m1_.thread_id
INNER JOIN Groups g2_ ON t0_.group_id = g2_.id
WHERE g2_.ownerUser_id = ?
ORDER BY m1_.timestamp DESC
LIMIT 4
Edit:
While reading the DQL "Limit" documentation, I came across the following:
If your query contains a fetch-joined collection specifying the result limit methods are not working as you would expect. Set Max Results restricts the number of database result rows, however in the case of fetch-joined collections one root entity might appear in many rows, effectively hydrating less than the specified number of results.
I'm pretty sure that I'm not doing a fetch-joined collection. I'm under the impression that a fetch-joined collection is where I do something like SELECT t, m FROM Threads JOIN t.messages. Am I incorrect in my understanding of this?
An update : With Doctrine 2.2+ you can use the Paginator http://docs.doctrine-project.org/en/latest/tutorials/pagination.html
Using ->groupBy('your_entity.id') seem to solve the issue!
I solved the same issue by only fetching contents of the master table and having all joined tables fetched as fetch="EAGER" which is defined in the Entity (described here http://www.doctrine-project.org/docs/orm/2.1/en/reference/annotations-reference.html?highlight=eager#manytoone).
class VehicleRepository extends EntityRepository
{
/**
* #var integer
*/
protected $pageSize = 10;
public function page($number = 1)
{
return $this->_em->createQuery('SELECT v FROM Entities\VehicleManagement\Vehicles v')
->setMaxResults(100)
->setFirstResult($number - 1)
->getResult();
}
}
In my example repo you can see I only fetched the vehicle table to get the correct result amount. But all properties (like make, model, category) are fetched immediately.
(I also iterated over the Entity-contents because I needed the Entity represented as an array, but that shouldn't matter afaik.)
Here's an excerpt from my entity:
class Vehicles
{
...
/**
* #ManyToOne(targetEntity="Makes", fetch="EAGER")
* #var Makes
*/
public $make;
...
}
Its important that you map every Entity correctly otherwise it won't work.