开发者

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 Thre开发者_运维知识库ad 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜