-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate EntityManager::merge #8461
Comments
This change will make it impossible to perform operations on entities (inserts, updates) without making a select request to a database. Merge is often used in the message queues jobs. |
@smilesrg Yes, but that is not necessarily bad. If you provide a detached entity in a message then the state it holds might already be outdated. It will be difficult to automatically reconcile these changes and the result might be, that your wrongly merged object is inserted instead. Whereas when you SELECT first and then manually merge in your domain you have more control over this and either with an appropriate message that tells users why the message could not be applied or manually merge in case it is safe. When using second level cache the additional select might not even result in an actual db query, if query count/performance is what you worry about. |
I understand that, but there are cases when performance prioritized over data integrity.
Yes, it is what I'm worrying about :-) second level cache is marked as experimental https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/second-level-cache.html Thanks for your great answer! |
@beberlei this ticket tagged as |
What is the solution for the usecase of a user's shopping basket? Fully persisting unfinished/in-progress baskets into the database and then doing more additional leg work for basket abandonment / clean up? |
This removal makes it difficult to properly implement the When sending a request similar to:
a new object should be created and the existing object with the same ID must be completely replaced (all existing states should be discarded). There is currently no easy way to do this natively with Doctrine ORM because You cannot attach a new object to an existing DB id (it may be possible using some methods marked as internal, but this is not a good long-term option). A workaround is to fetch the initial entity, set the new data, and reset untouched properties to their default values. This is doable using the reflection API, but this is cumbersome and hard to generalize in frameworks such as API Platform. In addition, this method is also probably slower than just creating a new object containing the new data. |
`EntityManager::merge()` has been deprecated in doctrine#8461 and removed in doctrine#9488. This PR removes a few remaining references and artefacts that - to my understanding - refer to it.
`EntityManager::merge()` has been deprecated in doctrine#8461 and removed in doctrine#9488. This PR removes a few remaining references and artefacts that - to my understanding - refer to it.
`EntityManager::merge()` has been deprecated in doctrine#8461 and removed in doctrine#9488. This PR removes a few remaining references and artefacts that - to my understanding - refer to it.
`EntityManager::merge()` has been deprecated in doctrine#8461 and removed in doctrine#9488. This PR removes a few remaining references and artefacts that - to my understanding - refer to it.
@dunglas I get the specification for PUT in HTTP, but its not logic that makes sense in terms of entities and objects. An entity in the database exists and replacing it by resetting all fields would be domain logic to implement on the users side, not an ORM concern. You can generically implement the logic in merge for PUT using ClassMetadata APIs such as setFieldValue. It does not require using internal APIs. |
The merge operation as used in the Java Persistence API is when you "Merges the state of a detached entity into the persistence context", meaning you have for example an entity unserialized from somewhere else (UI, API, Session) and you want the EntityManager to know about that object properly.
It is not a common PHP practice to serialize and move around data-objects to then synchronize and store them again in the database. As such the merge operation always felt a bit weird. Its existence even lead to Symfony serializing the user object into the session, where a proper approach would only serialize the identifier.
In addition the requirement to pass an entity and get a potentially different entity back from the method is cumbersome and unintuitive.
For us maintainers additionally, merging complex object graphs through
cascade=merge
always had bugs in edge cases that were hard to find and fix.Alternative:
If you use merge heavily, the alternative is instead to use
EntityManager::find
to fetch the actual entity with its current state from the database and then to update the state of this entity using the input/request data.Before:
After:
Third Party Alternatives:
The text was updated successfully, but these errors were encountered: