Forked here: https://github.com/dcousineau/doctrine2 though probably should pull it out into a local branch.
I went ahead and went down that route of altering hydrators to accept an array as well as a statement. This way uncached queries will work with the statement as it used to, but can also hydrate from an array.
As for the iterable hydrator you have a point but in this case you really can't cache it period, be it pre or post hydration (since to cache we have to serialize ALL the information).
What I have up is working(ish with the caveat that I backported the changes to an earlier tagged release for our application and tested using that), take a look and see if we like or don't like how I did it.
You'll notice I did split up _doExecute() for the query objects, because the DQL query object does so much analysis in the _doExecute() method which produces and attaches information (namely the result set mapping) that is depended on by the hydration process, I split it up into a "doPreExecute" function so that it can be called separately without actually executing the query.
It also avoids unnecessary "proxy not initialized, can't serialize" exceptions.