One-To-Many Bidirectional: Does not updates inverseSide cached collection. #5882

Open
opened 2026-01-22 15:21:09 +01:00 by admin · 8 comments
Owner

Originally created by @max-zu on GitHub (Feb 14, 2018).

Originally assigned to: @max-zu on GitHub.

I have two Entities Company and Storage with One-To-Many Bidirectional relationship. Entities and their relations are cached (doctrine second level cache). The issue is that, when i create a new Storage entity, Company storages collection doesn't have this new entity until I clear the cache manually.

AppBundle\Entity\Main\Company:
    type: entity
    table: main.company
    cache:
        usage: NONSTRICT_READ_WRITE
    id:
        id:
            type: integer
            nullable: false
            id: true
            generator:
                strategy: IDENTITY
    fields:
        legalName:
            type: string
            nullable: false
            length: 255
            options:
                fixed: false
            column: legal_name
    oneToMany:
      storages:
          targetEntity: AppBundle\Entity\Main\Storage
          mappedBy: company
          cascade: ["all"]
          orphanRemoval: true
          cache:
              usage: NONSTRICT_READ_WRITE
AppBundle\Entity\Main\Storage:
    type: entity
    table: main.storage
    cache:
        usage: NONSTRICT_READ_WRITE
    id:
        id:
            type: integer
            nullable: false
            options:
                unsigned: false
            id: true
            generator:
                strategy: IDENTITY
    fields:
        storageName:
            type: string
            nullable: true
            length: 255
            options:
                fixed: false
            column: storage_name

    manyToOne:
        company:
            targetEntity: AppBundle\Entity\Main\Company
            cascade: ["persist", "refresh"]
            fetch: LAZY
            mappedBy: null
            inversedBy: storages
            joinColumns:
                company_id:
                    referencedColumnName: id
            orphanRemoval: false
            cache:
                usage: NONSTRICT_READ_WRITE

I tried Doctrine 2.5./2.6./2.6.@dev
PHP 7.2/Postgres9.6/

Originally created by @max-zu on GitHub (Feb 14, 2018). Originally assigned to: @max-zu on GitHub. I have two Entities **Company** and **Storage** with One-To-Many Bidirectional relationship. Entities and their relations are cached (doctrine second level cache). The issue is that, when i create a new Storage entity, Company storages collection doesn't have this new entity until I clear the cache manually. ```yaml AppBundle\Entity\Main\Company: type: entity table: main.company cache: usage: NONSTRICT_READ_WRITE id: id: type: integer nullable: false id: true generator: strategy: IDENTITY fields: legalName: type: string nullable: false length: 255 options: fixed: false column: legal_name oneToMany: storages: targetEntity: AppBundle\Entity\Main\Storage mappedBy: company cascade: ["all"] orphanRemoval: true cache: usage: NONSTRICT_READ_WRITE ``` ```yaml AppBundle\Entity\Main\Storage: type: entity table: main.storage cache: usage: NONSTRICT_READ_WRITE id: id: type: integer nullable: false options: unsigned: false id: true generator: strategy: IDENTITY fields: storageName: type: string nullable: true length: 255 options: fixed: false column: storage_name manyToOne: company: targetEntity: AppBundle\Entity\Main\Company cascade: ["persist", "refresh"] fetch: LAZY mappedBy: null inversedBy: storages joinColumns: company_id: referencedColumnName: id orphanRemoval: false cache: usage: NONSTRICT_READ_WRITE ``` I tried Doctrine 2.5.*/2.6.*/2.6.@dev PHP 7.2/Postgres9.6/
admin added the BugMissing Tests labels 2026-01-22 15:21:09 +01:00
Author
Owner

@Ocramius commented on GitHub (Feb 14, 2018):

Requires a test case to reproduce the issue with a minimal scenario

@Ocramius commented on GitHub (Feb 14, 2018): Requires a test case to reproduce the issue with a minimal scenario
Author
Owner

@max-zu commented on GitHub (Feb 15, 2018):

186c6170e1
I used entities from Doctrine tests. Am i wrong, that when i create owning side Entity, i also need call addMethod() on inverse side ? Should the collection be updated automatically if I use cascade
operations ?

@max-zu commented on GitHub (Feb 15, 2018): https://github.com/max-zu/doctrine2/commit/186c6170e135ee6e55465f5e6d3803d7834f7d3e I used entities from Doctrine tests. Am i wrong, that when i create owning side Entity, i also need call addMethod() on inverse side ? Should the collection be updated automatically if I use cascade operations ?
Author
Owner

@lcobucci commented on GitHub (Feb 20, 2018):

@max-zu you're always responsible for setting both sides of the association.

@lcobucci commented on GitHub (Feb 20, 2018): @max-zu you're always responsible for setting both sides of the association.
Author
Owner

@max-zu commented on GitHub (Feb 20, 2018):

@lcobucci So what about Cascade Operations ??? If I have cascading links on the OwnerSide, why InverseSide collection is not updated?

@max-zu commented on GitHub (Feb 20, 2018): @lcobucci So what about Cascade Operations ??? If I have cascading links on the OwnerSide, why InverseSide collection is not updated?
Author
Owner

@lcobucci commented on GitHub (Feb 22, 2018):

@max-zu can you send the functional test as suggested by @Ocramius (it's way easier to understand what you're trying to achieve with that)?

@lcobucci commented on GitHub (Feb 22, 2018): @max-zu can you send the functional test as suggested by @Ocramius (it's way easier to understand what you're trying to achieve with that)?
Author
Owner

@nesk commented on GitHub (Jun 24, 2019):

@Ocramius Since the author didn't provided one, here's a test case to help you reproduce the bug: https://github.com/nesk/doctrine-cascade-refresh-showcase

git clone https://github.com/nesk/doctrine-cascade-refresh-showcase.git showcase
cd showcase
composer install
vendor/bin/doctrine orm:schema-tool:update --force
php run_showcase.php

The last command should output this:

REFRESH INVERSE SIDE (User)

    Draft user name: [draft] user
    Draft project name: [draft] project

    Reverted user name: user
    Reverted project name: [draft] project

REFRESH OWNING SIDE (Project)

    Draft user name: [draft] user
    Draft project name: [draft] project

    Reverted user name: user
    Reverted project name: project

The project has two entities, a User entity owns multiple Project entities. Both of them have the cascade={"refresh"} option on their relationship.

The run_showcase.php file creates one instance of each entity, links them and persists them.

We have two tests, the first one refreshes the inverse side (the User entity), the second one refreshes the owning side (the Project entity).

Each test edits the name of the two entities, outputs them, then refreshes one of the two entities and then outputs the names once again (both should have been replaced by the ones in the database).

You can see in the first test, the Project entity hasn't been refreshed, while in the second test, both of the entities have been properly refreshed.

@nesk commented on GitHub (Jun 24, 2019): @Ocramius Since the author didn't provided one, here's a test case to help you reproduce the bug: https://github.com/nesk/doctrine-cascade-refresh-showcase ```shell git clone https://github.com/nesk/doctrine-cascade-refresh-showcase.git showcase cd showcase composer install vendor/bin/doctrine orm:schema-tool:update --force php run_showcase.php ``` The last command should output this: ``` REFRESH INVERSE SIDE (User) Draft user name: [draft] user Draft project name: [draft] project Reverted user name: user Reverted project name: [draft] project REFRESH OWNING SIDE (Project) Draft user name: [draft] user Draft project name: [draft] project Reverted user name: user Reverted project name: project ``` The project has two entities, a `User` entity owns multiple `Project` entities. Both of them have the `cascade={"refresh"}` option on their relationship. The `run_showcase.php` file creates one instance of each entity, links them and persists them. We have two tests, the first one refreshes the inverse side (the `User` entity), the second one refreshes the owning side (the `Project` entity). Each test edits the name of the two entities, outputs them, then refreshes one of the two entities and then outputs the names once again (both should have been replaced by the ones in the database). You can see in the first test, the `Project` entity hasn't been refreshed, while in the second test, both of the entities have been properly refreshed.
Author
Owner

@nesk commented on GitHub (Mar 26, 2020):

Any news about this issue? I've provided a reproducible test case months, is there anything more I can do to help resolve this bug?

@nesk commented on GitHub (Mar 26, 2020): Any news about this issue? I've provided a reproducible test case months, is there anything more I can do to help resolve this bug?
Author
Owner

@nesk commented on GitHub (Mar 26, 2020):

So, I've been tweaking a bit the code, and the issue seems to be here: 8c259ea5cb/lib/Doctrine/ORM/UnitOfWork.php (L1825-L1828)

When the collection is unwrapped, it returns an empty array, because the PersistentCollection hasn't loaded the items.

Adding \iterator_to_array($relatedEntities); before the line 1827 solves the issue and the entities in the collection are properly refreshed. However, this doesn't seem to be the answer to the problem. The real issue is when you create and persist an entity which contains a filled ArrayCollection, once the entity is persisted, the filled ArrayCollection is replaced by an empty PersistentCollection.

Also, I'm not sure how all of this handles deleted entities in the collection?

@nesk commented on GitHub (Mar 26, 2020): So, I've been tweaking a bit the code, and the issue seems to be here: https://github.com/doctrine/orm/blob/8c259ea5cb632dbb57001b2262048ae7fa52b102/lib/Doctrine/ORM/UnitOfWork.php#L1825-L1828 When the collection is unwrapped, it returns an empty array, because the `PersistentCollection` hasn't loaded the items. Adding `\iterator_to_array($relatedEntities);` before the line `1827` solves the issue and the entities in the collection are properly refreshed. However, this doesn't seem to be the answer to the problem. The real issue is when you create and persist an entity which contains a filled `ArrayCollection`, once the entity is persisted, the **filled** `ArrayCollection` is replaced by an **empty** `PersistentCollection`. Also, I'm not sure how all of this handles deleted entities in the collection?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5882