doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.93k stars 2.51k forks source link

DDC-3212: Remove ArrayHydrator logic #3998

Open doctrinebot opened 10 years ago

doctrinebot commented 10 years ago

Jira issue originally created by user @ocramius:

The Doctrine\ORM\Internal\Hydration\ArrayHydrator ( https://github.com/doctrine/doctrine2/blob/85fbf684363b932a4ebaf543ef059f9ee1e512b0/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php ) is currently very messy and complicated due to the lack of actual Doctrine\ORM\UnitOfWork references when working with it, since we are not dealing with objects.

In order to reduce the amount of bugs and code duplication when working with array hydration, I would simply suggest making use of the Doctrine\ORM\Internal\Hydration\ObjectHydrator ( https://github.com/doctrine/doctrine2/blob/85fbf684363b932a4ebaf543ef059f9ee1e512b0/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php ) and its siblings, and then extracting data coming from the results in it as an array.

This could be a simple reflection-based extraction (pseudo):

class ArrayHydrator
{
    public function hydrateAllData()
    {
        foreach ($this->objectHydrator->hydrateAllData() as $object) {
            yield $this->extractData($object);
        }
    }
}

The point here is that array-based hydration is not the primary focus of the ORM, and users should probably rely on SQL only when they want array hydration.

doctrinebot commented 10 years ago

Comment created by @ocramius:

Note: performance is one of our biggest requirements, and array hydration is meant to achieve that. As I stated above, plain SQL is probably better for this sort of operation, so the issue is more about deprecating the ArrayHydrator completely, providing utilities to manipulate SQL resultsets instead.

doctrinebot commented 9 years ago

Comment created by SenseException:

I know of some intern projects, where the ArrayHydrator is used. It is right, that an ORM should be about objects, but that also counts for ScalarHydrator, and SingleScalarHydrator, which also aren't Object hydrator. Isn't there a way to reduce the complexity of the ArrayHydrator without ObjectHydrator? It would be a shame when a project build up with DQL Queries need to switch partially to SQL.

Ma27 commented 8 years ago

@Ocramius I'm against removing this feature. You are right, in some cases an array hydration may be odd, but it is helpful when trying to fetch a flat list of data: https://github.com/Sententiaregum/Sententiaregum/blob/master/src/AppBundle/Model/User/UserRepository.php#L83-L95 In this case I simply want to have the IDs (a complete hydration is in this case not necessary), so I do a partial select on the ids and then I transform it to a flat list using array_column().

If the array hydration will be removed in 3.x, I don't see a simple way to fetch flat lists only or will be there some other approach to do that? And yes, I'd like to use DQL for this since I love the way to think in models although I just need to fetch a flat list in that case.

kimhemsoe commented 8 years ago

@Ma27 I think the same can be achieved with a simple "SELECT u.id FROM MyApp\User u"

Ma27 commented 8 years ago

but when I run an object hydration, this is the only value that will be attached on the object or am I wrong?

Ocramius commented 8 years ago

@Ma27 no, that would be partial hydration, which is expressed with a different (very specific) syntax (see http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#partial-object-syntax )

badrutdinovrr commented 4 years ago

Unfortunately, object hydration is very very very slow. So array hydration is really useful when performance matters. Using sql breaks mapping incapsulation completely, so it's much better to use dql for such cases.