Sorry for reopening Jon but I think there might be a valid issue here still. While we agree that local changes in objects are generally considered newer and not overriden by queries from the database this here is something different I think. I'll try to make it clear:
When any object is hydrated, we pick the PK and first look in the identity map ("session cache"). If it is there, we take that and put it in the query result.
OK. But this issue seems to demonstrate that this is not happening, at least on joined single-valued associations. The second query returns the associated object with ID 2. So Doctrine should try to look up that object with ID 2 in the identity map and if its not there construct it and put it there. Instead Doctrine currently seems to just retain anything that is set in the association.
So I think that needs to be fixed by not blindly retaining what is there but instead by picking the PK of the joined record/entity that was returned by the query and then looking that up as usual in the identity map. If it is found there, we take that object and if not we construct it and put it there.
This might also affect Doctrine 2 so I will copy this issue there for further investigation, too.