duanpin9531
2017-01-17 10:48
浏览 25
已采纳

Doctrine - 在ArrayCollection中对子进行更改。 坚持父母。 儿童的变化不会持续存在

Background: A Pitch can contain many Visuals. The Visuals are stored as a property on Pitch in an ArrayCollection.

Here's a quick diagram of the Visuals table (visuals), the Pitches table (statuses_pitch) and the join table created by Doctrine as a result.

Schema

enter image description here

Pitch

Here's the relevant mapping information for Pitch. Visual has no mapping back to Pitch because the relationship is unidirectional.

manyToMany:
    visuals:
        targetEntity: Visual
        cascade: ['persist', 'refresh', 'remove']
        fetch: EAGER
        orphanRemoval: true
        joinTable:
            name: pitches_visuals
            joinColumns:
                pitch_id:
                    referencedColumnName: id
            inverseJoinColumns:
                visual_id:
                    referencedColumnName: id

I am making the changes to a Visual in the ArrayCollection of Pitch and then calling $em->persist($pitch) and $em->flush($pitch). The changes to the child Visual are not persisted to the database as I expect.

Before Persisting

Here's what the Pitch object looks like before I persist it. Note that the Visual objects have a visualType property (mapped to visual_type in the db). These are not null when persisting.

visual not null

After Persisting

Here's the database table after persisting. Note that the visual_type column still has null in there and the change was not persisted.

visual is null

I have tried

- Through complete laziness thrown cascades all over the place, to no avail
- Changed the cascade refresh from the owning (pitch) to inverse (visual) side
- Looked through the docs to see if cascade refresh is affected specifically in a Many-To-Many relationship - I couldn't find anything concrete on this, or if there *is* a problem, how I would get around it

How can I achieve what I need here, by making a change to

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongrongdao8902 2017-01-17 12:46
    已采纳

    Looking at the method signature of EntityManager::flush yields the following information:

    Flushes all changes to objects that have been queued up to now to the database. This effectively synchronizes the in-memory state of managed objects with the database. If an entity is explicitly passed to this method only this entity and the cascade-persist semantics + scheduled inserts/removals are synchronized.

    Looks like this doesn't involve updates (cascade: refresh).

    So in short, I had to change $em->flush($entity) to $em->flush() to allow refresh cascades to execute. This required an architecture re-think so I'm not calling flush() multiple times for no reason.

    已采纳该答案
    打赏 评论

相关推荐 更多相似问题