Problem with ObjectHydrator #5091

Closed
opened 2026-01-22 14:58:04 +01:00 by admin · 2 comments
Owner

Originally created by @raziel057 on GitHub (Apr 12, 2016).

Originally assigned to: @Ocramius on GitHub.

I've just noticed this weird behaviour:

Considering I have an entity "area" which contains a collection of "badges".
With "area" ID1 contains (Badge ID2, Badge ID3, Badge ID4)

  • I make a request to find a list of objects with a specific Item in collection (areas with badge id 2).
  • I make a second request to find an object (which was in the previous list) with all the linked badge.

But when I get the badge entity, I only the badge id 2 in collection. Is it a known behavior (cache in Object hydratator) or a bug? For me, as the query is different, we can't reuse the same object, so it seems to be an issue but can you please confirm.

Example:

$areas = $this->entityManager->createQueryBuilder()
    ->select('a, b')
    ->from('PTCNoventoBundle:Area', 'a')
    ->join('a.badges', 'b', 'WITH', 'b.id = :badgeId')
    ->setParameter('badgeId', 2)
    ->getQuery()->useResultCache(false)->getResult();

dump($areas);

Result:

array:8 [▼
  0 => Area {#2646 ▶}
  1 => Area {#2676 ▶}
  2 => Area {#2681 ▶}
  3 => Area {#2686 ▶}
  4 => Area {#2691 ▶}
  5 => Area {#2696 ▶}
  6 => Area {#2701 ▶}
  7 => Area {#2706 ▶}
]
$area = $this->entityManager->createQueryBuilder()
    ->select('a, b')
    ->from('PTCNoventoBundle:Area', 'a')
    ->join('a.badges', 'b')
    ->where('a.id = :id')
    ->setParameter('id', 1)
    ->getQuery()->expireResultCache()->getSingleResult();

dump($area);
Area {#2646 ▼
  -id: 1
  -name: "RED"
  -color: "FF0000"
  -badges: PersistentCollection {#2620 ▼
    -snapshot: array:1 [ …1]
    -owner: Area {#2646}
    -association: array:21 [ …21]
    -em: EntityManager {#1066 …11}
    -backRefFieldName: null
    -typeClass: ClassMetadata {#449 …}
    -isDirty: false
    #collection: ArrayCollection {#2640 ▼
      -elements: array:1 [▼
        2 => Badge {#2653 ▶}
      ]
    }
    #initialized: true
  }
  #createdAt: DateTime {#2649 ▶}
  #updatedAt: DateTime {#2648 ▶}
  -logEnabled: true
}
Originally created by @raziel057 on GitHub (Apr 12, 2016). Originally assigned to: @Ocramius on GitHub. I've just noticed this weird behaviour: Considering I have an entity "area" which contains a collection of "badges". With "area" ID1 contains (Badge ID2, Badge ID3, Badge ID4) - I make a request to find a list of objects with a specific Item in collection (areas with badge id 2). - I make a second request to find an object (which was in the previous list) with all the linked badge. But when I get the badge entity, I only the badge id 2 in collection. Is it a known behavior (cache in Object hydratator) or a bug? For me, as the query is different, we can't reuse the same object, so it seems to be an issue but can you please confirm. Example: ``` php $areas = $this->entityManager->createQueryBuilder() ->select('a, b') ->from('PTCNoventoBundle:Area', 'a') ->join('a.badges', 'b', 'WITH', 'b.id = :badgeId') ->setParameter('badgeId', 2) ->getQuery()->useResultCache(false)->getResult(); dump($areas); ``` Result: ``` array:8 [▼ 0 => Area {#2646 ▶} 1 => Area {#2676 ▶} 2 => Area {#2681 ▶} 3 => Area {#2686 ▶} 4 => Area {#2691 ▶} 5 => Area {#2696 ▶} 6 => Area {#2701 ▶} 7 => Area {#2706 ▶} ] ``` ``` php $area = $this->entityManager->createQueryBuilder() ->select('a, b') ->from('PTCNoventoBundle:Area', 'a') ->join('a.badges', 'b') ->where('a.id = :id') ->setParameter('id', 1) ->getQuery()->expireResultCache()->getSingleResult(); dump($area); ``` ``` Area {#2646 ▼ -id: 1 -name: "RED" -color: "FF0000" -badges: PersistentCollection {#2620 ▼ -snapshot: array:1 [ …1] -owner: Area {#2646} -association: array:21 [ …21] -em: EntityManager {#1066 …11} -backRefFieldName: null -typeClass: ClassMetadata {#449 …} -isDirty: false #collection: ArrayCollection {#2640 ▼ -elements: array:1 [▼ 2 => Badge {#2653 ▶} ] } #initialized: true } #createdAt: DateTime {#2649 ▶} #updatedAt: DateTime {#2648 ▶} -logEnabled: true } ```
admin added the BugInvalid labels 2026-01-22 14:58:04 +01:00
admin closed this issue 2026-01-22 14:58:04 +01:00
Author
Owner

@Ocramius commented on GitHub (Apr 12, 2016):

You are filtering on a fetch-join (a and b are both selected), which will break hydration.

While this is supported, it is a risky operations, and you shouldn't do it, ever.

The problem is that a entries will only have a subset of b entries it actually references, and by hydrating the results this way you are also keeping this inconsistent state in memory.

See also http://stackoverflow.com/questions/13603054/doctrine-fetch-join

@Ocramius commented on GitHub (Apr 12, 2016): You are filtering on a fetch-join (`a` and `b` are both selected), which will break hydration. While this is supported, it is a risky operations, and you shouldn't do it, ever. The problem is that `a` entries will only have a subset of `b` entries it actually references, and by hydrating the results this way you are also keeping this inconsistent state in memory. See also http://stackoverflow.com/questions/13603054/doctrine-fetch-join
Author
Owner

@raziel057 commented on GitHub (Apr 12, 2016):

Ok thanks for your reply.

@raziel057 commented on GitHub (Apr 12, 2016): Ok thanks for your reply.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5091