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
DeepCopy ignores Doctrine2 proxies #18
Comments
Yep, it was already reported in #15 but in a less explicit way so I've closed it in favor of this issue. |
Can confirm that I have same issue. |
We have this issue too, any news ? |
Nothing new, I'd gladly merge new filters (DoctrineProxyFilter?) and matchers (DoctrineProxyMatcher?) if anyone is up to doing it. Please note that the current architecture of this package allows you to solve that problem already (thanks to the extension points). The idea is that you can make this package fit all your needs (e.g. support any kind of 3rd party library, not only Doctrine). But I'm OK to merge Doctrine support in the main package. |
AFAIK, there is no way You cound extract original |
if ($object instanceof \Doctrine\Common\Persistence\Proxy) {
$object->__load();
} That will trigger loading the object behind the proxy (see https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Persistence/Proxy.php#L51). Then maybe also it's necessary to ignore the proxy's own properties? (https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Proxy/ProxyGenerator.php#L87-L101) |
FYI the proxy is the same object as the original entity. The proxy will intercept all method/property calls to load the properties in the same object. |
Try this at Your own, and You will see. problem is that each property in
Problem is, that firstly You need to hydrate inner object, and only then You can skip
That's why originally I created a #22 to override how refrection is created:
|
Proxy is NOT the same as original Entity. It extends original entity. It even 'lives' in other |
Yep that's exactly what I said in my comment above ;) It's doable with filters and I'm accepting pull requests that fix this correctly.
You are confusing classes and objects :) The entity and the proxy are the same object (aka instance). They are indeed not the same class, but that doesn't matter because I only said that to explain that your sentence "You cound extract original Entity from Proxy" makes no sense in this context. |
What I was trying to say that it is same only when You interact with it. It's not the same when You have a |
I don't see why it wouldn't work with a |
So, that's a +1 from me |
I have the same issue on every object entity that I want to clone, including ones in ArrayCollection. |
Hi! This problem resurged to me (I created #15 a year ago) and clearing the unit of work and re-querying the entity does not solve my problem anymore, because the new query also returns a proxy as well. I'm going to try to solve the root of problem. Wish me luck 😀 |
About this, I solved this problem by cloning every entity in a collection. My catalog has a collection of categories, and each category has a collection of products.
For huge catalogs, I had to modify the script execution time to make it work :
It works for me. |
@eved42 - don't forget, that you're also cloning the the entire |
@vbartusevicius that's exactly the problem I'm facing. The library tries to clone a huge graph with all that references to the EntityManager and it runs out of memory. If I set the memory limit to -1 then the script dies at the 60 seconds of execution. Clearly that is no quality software |
You could write filters and matchers (https://github.com/myclabs/DeepCopy#going-further) to filter out the properties that reference to the entity manager (that's what filters and matchers are for). Also make sure you are using the existing Doctrine collection filters too: https://github.com/myclabs/DeepCopy#doctrinecollectionfilter |
Ok, while trying to solve my original problem I found out that DeepCopy is not having issues with cloning proxies. My memory limit problem was a circular reference in my model (which isn't wrong, just needed a KeepFilter in one attribute), but a deep debug on the library revealed that the proxies doesn't hold references to the entityManager as @vbartusevicius suggested. There is 3 attributes in a proxy that doesn't belong to the original entities:
In my code I'm doing a previous query to the database, then I fetch the entity to clone (it returns as an instance of I debugged the memory consumption and generated a graph of all the functions that are getting called and how much memory is this taking. Have a look! |
Congrats to @malc0mn for solving this 2 year old issue with 2 actual lines of code :) |
Correct me if I am wrong (and totally stupid), but could it be that the ProxyFilter (it matches every property since it is not checked) is executed and returns after it at this line ? So no other filter is executed? I have an ProxyClass of an entity and i am using it the following way: $copyHelper = new DeepCopy();
$copyHelper->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher());
$copyHelper->addFilter(new SetNullFilter(), new PropertyNameMatcher('id')); the second filter is never called on the property because the DoctrineProxyFilter matched first. Best, |
@IMM0rtalis yes that sounds correct, but I'm not sure what the problem is, the issue has been closed, maybe you should open a separate ticket to explain the problem? |
The problem is not solved. I can't affect doctrine to load true model instead of proxies (without unit of work hack). So when copyObject method reachs this proxy model it just returns object and will not follow all it's properties, because proxy model has __clone method. If I will not use flag useCloneMethod it will not copy correctly PersistentCollection.
Any ideas? Maybe I'm missing something.. |
@alvery did you see that you need to register a filter for it? (see https://github.com/myclabs/DeepCopy#doctrineproxyfilter-filter or #18 (comment)) |
@theofidry Sure, it's the next line after
|
The filter should kick in before Just make sure you are on the last version and if the problem persist I would need a reproducer please, I cannot really check it at the moment. Also just in case since you mentioned a collection, there is more than one doctrine filter so make sure you have the right one registered |
If the relation is fully hydrated (ie, no proxy) everything is good, and my "id" property matcher can set the property to null.
If, however, the relation isn't retrieved in the query, the related object is Proxy instance, and DeepCopy won't set the ID of that object to null.
Has anyone had this problem, and has anyone got a workaround, other than hydrating everything before copying (which might be the most sensible thing to do anyway)?
The text was updated successfully, but these errors were encountered: