DDC-1734: Uninitialized proxies cannot be serialized properly #2181

Closed
opened 2026-01-22 13:43:25 +01:00 by admin · 28 comments
Owner

Originally created by @doctrinebot on GitHub (Mar 29, 2012).

Originally assigned to: @Ocramius on GitHub.

Jira issue originally created by user benjamin:

I have the following entity:

class Currency
{
    /*** @Id @Column(type="string") **/
    protected $code;

    /*** @Column(type="string") **/    
    protected $name;
}

When I serialize an object graph which references a Currency proxy, but this proxy is initialized, then this works as expected:

O:65:"Application\Domain\Proxy\*_CG__\Application\Domain\Model\Currency":3:{s:17:"__isInitialized_*";b:1;s:7:"**code";s:3:"USD";s:7:"**name";s:20:"United States Dollar";}

However, if the proxy is not initialized, then all properties are serialized as null, and the identity is lost:

O:65:"Application\Domain\Proxy\*_CG__\Application\Domain\Model\Currency":3:{s:17:"__isInitialized_*";b:0;s:7:"**code";N;s:7:"**name";N;}

That makes a merge() impossible once stored in a session, as the identity of the entity is now unknown.

I think the solution might be:

  • either to have the proxy's $_identity field serialized as well
  • or to have the $code (identity field) populated when the proxy is created.
Originally created by @doctrinebot on GitHub (Mar 29, 2012). Originally assigned to: @Ocramius on GitHub. Jira issue originally created by user benjamin: I have the following entity: ``` class Currency { /*** @Id @Column(type="string") **/ protected $code; /*** @Column(type="string") **/ protected $name; } ``` When I serialize an object graph which references a Currency proxy, but this proxy is initialized, then this works as expected: ``` O:65:"Application\Domain\Proxy\*_CG__\Application\Domain\Model\Currency":3:{s:17:"__isInitialized_*";b:1;s:7:"**code";s:3:"USD";s:7:"**name";s:20:"United States Dollar";} ``` However, if the proxy is not initialized, then all properties are serialized as null, and the identity is lost: ``` O:65:"Application\Domain\Proxy\*_CG__\Application\Domain\Model\Currency":3:{s:17:"__isInitialized_*";b:0;s:7:"**code";N;s:7:"**name";N;} ``` That makes a merge() impossible once stored in a session, as the identity of the entity is now unknown. I think the solution might be: - either to have the proxy's $_identity field serialized as well - or to have the $code (identity field) populated when the proxy is created.
admin added the Bug label 2026-01-22 13:43:25 +01:00
admin closed this issue 2026-01-22 13:43:27 +01:00
Author
Owner

@doctrinebot commented on GitHub (Mar 29, 2012):

@doctrinebot commented on GitHub (Mar 29, 2012): - is referenced by [DDC-3368: [GH-1172] Don't initialize detached proxies when merging them.](http://www.doctrine-project.org/jira/browse/DDC-3368)
Author
Owner

@doctrinebot commented on GitHub (Apr 3, 2012):

Comment created by @ocramius:

I am personally for dropping the $_identifier field and using the entity fields themselves. Will check this tomorrow. (also: not sure if it is possible, just checking)

@doctrinebot commented on GitHub (Apr 3, 2012): Comment created by @ocramius: I am personally for dropping the `$_identifier` field and using the entity fields themselves. Will check this tomorrow. (also: not sure if it is possible, just checking)
Author
Owner

@doctrinebot commented on GitHub (Apr 7, 2012):

Comment created by @beberlei:

This is not fixable. The Proxy requires access to the Entity Persister when unserialized, but that is not available anymore. Proxies are broken if unserialized and then accessed, i believe an exception is thrown in this case.

@doctrinebot commented on GitHub (Apr 7, 2012): Comment created by @beberlei: This is not fixable. The Proxy requires access to the Entity Persister when unserialized, but that is not available anymore. Proxies are broken if unserialized and then accessed, i believe an exception is thrown in this case.
Author
Owner

@doctrinebot commented on GitHub (Apr 7, 2012):

Comment created by benjamin:

Of course they cannot be initialized once unserialized, but should'nt be merge()able to a new EntityManager anyway?

What I would imagine is:

@doctrinebot commented on GitHub (Apr 7, 2012): Comment created by benjamin: Of course they cannot be initialized once unserialized, but should'nt be merge()able to a new EntityManager anyway? What I would imagine is: - Serialize the identity as part of the proxy - If used when unserialized, throw an exception (see http://www.doctrine-project.org/jira/browse/[DDC-1732](http://www.doctrine-project.org/jira/browse/DDC-1732)) - If found during a merge(), replace the proxy with a fresh proxy/entity from the current EntityManager
Author
Owner

@doctrinebot commented on GitHub (Oct 30, 2012):

Comment created by benjamin:

@Marco Pivetta This is a great idea. Have you checked if it is possible?
I'm really surprised that a proxied entity's identity is lost forever upon serialization.

@doctrinebot commented on GitHub (Oct 30, 2012): Comment created by benjamin: @Marco Pivetta This is a great idea. Have you checked if it is possible? I'm really surprised that a proxied entity's identity is lost forever upon serialization.
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by mnapoli:

Can this issue be reopened please?

As Benjamin Morel said, it is expected that the proxy is broken once unserialized, but it should be possible to merge to the EntityManager and then use it.

For now, objects graphs with proxies can't be serialized! It could be if the merge would resolve the situation.

I'm giving it a try by serializing the $_identifier field in the Proxy

Thanks

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by mnapoli: Can this issue be reopened please? As Benjamin Morel said, it is expected that the proxy is broken once unserialized, but it should be possible to merge to the EntityManager and then use it. For now, objects graphs with proxies can't be serialized! It could be if the merge would resolve the situation. I'm giving it a try by serializing the $_identifier field in the Proxy Thanks
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

[~benjamin] you can check my implementation for DCOM-96 at https://github.com/doctrine/common/pull/168 and https://github.com/doctrine/doctrine2/pull/406

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: [~benjamin] you can check my implementation for [DCOM-96](http://www.doctrine-project.org/jira/browse/DCOM-96) at https://github.com/doctrine/common/pull/168 and https://github.com/doctrine/doctrine2/pull/406
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

[~matthieu] can you try adding $identifier at https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Proxy/ProxyFactory.php#L319-L323 ?

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: [~matthieu] can you try adding $identifier at https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Proxy/ProxyFactory.php#L319-L323 ?
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by mnapoli:

[~ocramius] Yes that's what I'm planning to do. I've written a testcase that reproduces the bug right now.

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by mnapoli: [~ocramius] Yes that's what I'm planning to do. I've written a testcase that reproduces the bug right now.
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

[~matthieu] awesome. If you can attach the test here, it would be possible to add it to the proxy refactoring.

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: [~matthieu] awesome. If you can attach the test here, it would be possible to add it to the proxy refactoring.
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by mnapoli:

@ocramius I will make a pull request on Github and post the link here.

However I'm sort of stuck right now: I've added '_identifier' to the fields serialized, but it's not enough. To merge, the UoW needs to initialize the proxy to get the identifiers (because $_identifier is private in the proxy). Problem: $_entityPersister (used to initialize the proxy) is also private.

So I can neither get the identifier of the proxy (even for creating a new proxy for example), nor feed it a new entityPersister to load it... The solution would be to change the proxy a bit (like adding a "**setEntityPersister" method for example) but I guess that changing the Proxy interface in "Doctrine\Common" is a large change and that will not be accepted as a pull request...

Any ideas ?

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by mnapoli: @ocramius I will make a pull request on Github and post the link here. However I'm sort of stuck right now: I've added '_identifier' to the fields serialized, but it's not enough. To merge, the UoW needs to initialize the proxy to get the identifiers (because $_identifier is private in the proxy). Problem: $_entityPersister (used to initialize the proxy) is also private. So I can neither get the identifier of the proxy (even for creating a new proxy for example), nor feed it a new entityPersister to load it... The solution would be to change the proxy a bit (like adding a "**setEntityPersister" method for example) but I guess that changing the Proxy interface in "Doctrine\Common" is a large change and that will not be accepted as a pull request... Any ideas ?
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

[~matthieu] I wouldn't start hacking on that right now... The new impl allows injecting an initializer. A hack may be ok-ish, but the API is already at its EOL.

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: [~matthieu] I wouldn't start hacking on that right now... The new impl allows injecting an initializer. A hack may be ok-ish, but the API is already at its EOL.
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

[~matthieu] I'd think of marking this as to be fixed in 2.4.x

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: [~matthieu] I'd think of marking this as to be fixed in 2.4.x
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by mnapoli:

[~ocramius] I'm working on the master branch, it's 2.4 right? I don't see anything different for the proxies in this branch (I don't see any way to inject an initializer).

Or is it your PR (https://github.com/doctrine/common/pull/168) maybe?

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by mnapoli: [~ocramius] I'm working on the master branch, it's 2.4 right? I don't see anything different for the proxies in this branch (I don't see any way to inject an initializer). Or is it your PR (https://github.com/doctrine/common/pull/168) maybe?
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by benjamin:

I'm happy that this bug is taken care of, I think that's a major problem that's been dismissed a bit quickly.
Can the bug be reopened, with fix version 2.4, to avoid forgetting it once more?

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by benjamin: I'm happy that this bug is taken care of, I think that's a major problem that's been dismissed a bit quickly. Can the bug be reopened, with fix version 2.4, to avoid forgetting it once more?
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by mnapoli:

[~benjamin] +1

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by mnapoli: [~benjamin] +1
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

[~mnapoli] yes, that's the PR. Please let me know for the tests so that I can add them to doctrine/common.
I'm re-opening the issue

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: [~mnapoli] yes, that's the PR. Please let me know for the tests so that I can add them to doctrine/common. I'm re-opening the issue
Author
Owner

@doctrinebot commented on GitHub (Nov 30, 2012):

Comment created by @ocramius:

Re-opening issue - need test to verify the behavior before proceeding.

@doctrinebot commented on GitHub (Nov 30, 2012): Comment created by @ocramius: Re-opening issue - need test to verify the behavior before proceeding.
Author
Owner

@doctrinebot commented on GitHub (Dec 3, 2012):

Comment created by mnapoli:

[~ocramius] Sorry the test was on my computer at work, here it is now: https://gist.github.com/4193721

Just to be clear: I created 2 test methods, the first one works (there is no serialization step), the second doesn't. This is to make it clear that the serialization step is the problem. I hope this is alright.

@doctrinebot commented on GitHub (Dec 3, 2012): Comment created by mnapoli: [~ocramius] Sorry the test was on my computer at work, here it is now: https://gist.github.com/4193721 Just to be clear: I created 2 test methods, the first one works (there is no serialization step), the second doesn't. This is to make it clear that the serialization step is the problem. I hope this is alright.
Author
Owner

@doctrinebot commented on GitHub (Dec 3, 2012):

Comment created by @ocramius:

[~mnapoli] thank you for the test. But please fix the tests so that both fail (if these are actually two verified cases).

@doctrinebot commented on GitHub (Dec 3, 2012): Comment created by @ocramius: [~mnapoli] thank you for the test. But please fix the tests so that both fail (if these are actually two verified cases).
Author
Owner

@doctrinebot commented on GitHub (Dec 3, 2012):

Comment created by mnapoli:

[~ocramius] No those aren't 2 different cases, they are the same, it's just that one fails because we use serialization (this is the problem described in this ticket), and the other one works because we don't use serialization (and it only exists to check that everything works if we don't use serialization). Actually I think the "working test" has no reason to exist really, I just made it to "prove" that the problem was indeed the serialization, so it can be removed.

@doctrinebot commented on GitHub (Dec 3, 2012): Comment created by mnapoli: [~ocramius] No those aren't 2 different cases, they are the same, it's just that one fails because we use serialization (this is the problem described in this ticket), and the other one works because we don't use serialization (and it only exists to check that everything works if we don't use serialization). Actually I think the "working test" has no reason to exist really, I just made it to "prove" that the problem was indeed the serialization, so it can be removed.
Author
Owner

@doctrinebot commented on GitHub (Dec 3, 2012):

Comment created by @ocramius:

[~mnapoli] ok, so I can basically strip the working one :)

@doctrinebot commented on GitHub (Dec 3, 2012): Comment created by @ocramius: [~mnapoli] ok, so I can basically strip the working one :)
Author
Owner

@doctrinebot commented on GitHub (Jan 6, 2013):

Comment created by @ocramius:

[~mnapoli] I deployed a fix in DCOM-96 ( https://github.com/doctrine/doctrine2/pull/406 https://github.com/Ocramius/doctrine2/commit/1424cc781277a4f8183229c5e8d838724e1ca879 )

@doctrinebot commented on GitHub (Jan 6, 2013): Comment created by @ocramius: [~mnapoli] I deployed a fix in [DCOM-96](http://www.doctrine-project.org/jira/browse/DCOM-96) ( https://github.com/doctrine/doctrine2/pull/406 https://github.com/Ocramius/doctrine2/commit/1424cc781277a4f8183229c5e8d838724e1ca879 )
Author
Owner

@doctrinebot commented on GitHub (Jan 15, 2013):

Comment created by mnapoli:

[~ocramius] fantastic!

@doctrinebot commented on GitHub (Jan 15, 2013): Comment created by mnapoli: [~ocramius] fantastic!
Author
Owner

@doctrinebot commented on GitHub (Jan 25, 2013):

Comment created by @beberlei:

A related Github Pull-Request [GH-247] was opened
https://github.com/doctrine/common/pull/247

@doctrinebot commented on GitHub (Jan 25, 2013): Comment created by @beberlei: A related Github Pull-Request [GH-247] was opened https://github.com/doctrine/common/pull/247
Author
Owner

@doctrinebot commented on GitHub (Jan 26, 2013):

Comment created by @beberlei:

A related Github Pull-Request [GH-247] was closed
https://github.com/doctrine/common/pull/247

@doctrinebot commented on GitHub (Jan 26, 2013): Comment created by @beberlei: A related Github Pull-Request [GH-247] was closed https://github.com/doctrine/common/pull/247
Author
Owner

@doctrinebot commented on GitHub (Feb 21, 2013):

Comment created by @ocramius:

Resolved in DCOM-96

@doctrinebot commented on GitHub (Feb 21, 2013): Comment created by @ocramius: Resolved in [DCOM-96](http://www.doctrine-project.org/jira/browse/DCOM-96)
Author
Owner

@doctrinebot commented on GitHub (Feb 21, 2013):

Issue was closed with resolution "Fixed"

@doctrinebot commented on GitHub (Feb 21, 2013): Issue was closed with resolution "Fixed"
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#2181