You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Lon Varscsak <lo...@gmail.com> on 2019/02/06 23:07:17 UTC

Cayenne and Serialization

Hey all,

Recently I switched to 4.1's field based data objects (I've been using
4/4.1 for a while, but using the Map based objects) and I ran into an
issue.  It appears that when using this type of object, the
de-serialization results in an object that is not usable.  It results in a
HOLLOW object that returns null for all of its values.  This object is in a
COMMITTED state to start (no changes), so it really shouldn't be doing
anything special with serialization, but something is amiss.

To set the stage: So the object is called Site, it's PK is called siteId.
I fetch an object, I then serialize that object (normally the web framework
would choose when to, but I've create some test code to verify this), I
then deserialize the object.  Now when I call get*AnyAttribute*() on the
deserialized Site object, they all return null and the object is HOLLOW.
In the Map based template, the object is still hollow, but all of the
properties will return a value.

Something else that really surprised me (just because of how long I've been
working with this code) is that the deserialized object in both cases no
longer have an object context.  Not sure how I haven't encountered a
problem with that before.

Any thoughts?

-Lon

Re: Cayenne and Serialization

Posted by Andrus Adamchik <an...@objectstyle.org>.
>> What do you mean by the root? 

Sorry, I was not very precise with my definition. I meant a "logical" root. The order of serialization (context first or objects first) shouldn't matter. On deserialization DataContext would reattach all its child objects to itself.

>  It also appears that if you use parent/child contexts, even if you
> serialize both contexts, the child context doesn't remember that it's
> parent channel was another context.

Correct. Part of the reason is that the parent of a context is a DataChannel. I.e. it can be either DataContext (that is serializable) or a DataDomain (that can not and should not be serialized). So we keep the "channel" ivar as transient, leaving it up to the caller to reattach it properly. 

While we can probably force parent serialization when "channel instanceof ObjectContext", I am afraid we may introduce an issue similar to what we expected to happen with DataObjects (i.e. serializing a single seemingly small thing results in serializing your world).

So please remind me, what is the scenario (and desired behavior) for serializing contexts and objects in your case? Maybe we can brainstorm some fresh ideas.

And did I say how much I "love" Java serialization?

Andrus


> On Mar 8, 2019, at 2:29 AM, Lon Varscsak <lo...@gmail.com> wrote:
> 
> It also appears that if you use parent/child contexts, even if you
> serialize both contexts, the child context doesn't remember that it's
> parent channel was another context.
> 
> -Lon
> 
> On Wed, Feb 27, 2019 at 4:16 PM Lon Varscsak <lo...@gmail.com> wrote:
> 
>> There's unfortunately no clean solution for an "unmanaged"
>>> (de)serialization of the context-attached auto-expanding object graph. The
>>> one we have right now, that requires the context to be the serialization
>>> "root", seems like the best choice out of the available options.
>> 
>> 
>> Can you expand on this a little bit?  What do you mean by the root?  So
>> far I find that if I serialize the ObjectContext with the data objects (two
>> fields in my web page that's getting serialized as an example) things seem
>> to work.  Is this just a coincidence?  What if I serialize them in a
>> different order (but both serialized?)
>> 
>> -Lon
>> 


Re: Cayenne and Serialization

Posted by Lon Varscsak <lo...@gmail.com>.
It also appears that if you use parent/child contexts, even if you
serialize both contexts, the child context doesn't remember that it's
parent channel was another context.

-Lon

On Wed, Feb 27, 2019 at 4:16 PM Lon Varscsak <lo...@gmail.com> wrote:

> There's unfortunately no clean solution for an "unmanaged"
>> (de)serialization of the context-attached auto-expanding object graph. The
>> one we have right now, that requires the context to be the serialization
>> "root", seems like the best choice out of the available options.
>
>
> Can you expand on this a little bit?  What do you mean by the root?  So
> far I find that if I serialize the ObjectContext with the data objects (two
> fields in my web page that's getting serialized as an example) things seem
> to work.  Is this just a coincidence?  What if I serialize them in a
> different order (but both serialized?)
>
> -Lon
>

Re: Cayenne and Serialization

Posted by Lon Varscsak <lo...@gmail.com>.
>
> There's unfortunately no clean solution for an "unmanaged"
> (de)serialization of the context-attached auto-expanding object graph. The
> one we have right now, that requires the context to be the serialization
> "root", seems like the best choice out of the available options.


Can you expand on this a little bit?  What do you mean by the root?  So far
I find that if I serialize the ObjectContext with the data objects (two
fields in my web page that's getting serialized as an example) things seem
to work.  Is this just a coincidence?  What if I serialize them in a
different order (but both serialized?)

-Lon

Re: Cayenne and Serialization

Posted by Andrus Adamchik <an...@objectstyle.org>.
> I'm sure there's a good explanation for this.

The explanation is that if an object has a serializable reference to the context, serializing a single object would also serialize the context ... and all the objects in the context. If unsuspected developers serialize N individual objects at once, they will be creating N huge copies of the context and its contents.

There's unfortunately no clean solution for an "unmanaged" (de)serialization of the context-attached auto-expanding object graph. The one we have right now, that requires the context to be the serialization "root", seems like the best choice out of the available options.

Andrus

> On Feb 26, 2019, at 12:59 PM, Lon Varscsak <lo...@gmail.com> wrote:
> 
> So reviving this topic (which is different than the one I just posted
> separately), if I archive the DataContext myself along with the object, all
> works as I'd expect (objectContext is not null and I get values back from
> the object).  I guess I was just surprised that in the case of a Web
> application, where the serialization of an object is outside my knowledge
> (like when a framework might archive pages to save on memory) that I would
> also have to remember to have a reference to (so it would also serialize)
> the DataContext.  It happens that I almost always do, but sometimes one
> might fetch some stuff with a context that they don't have a reference to
> and would get this issue.
> 
> I'm sure there's a good explanation for this.
> 
> On Thu, Feb 7, 2019 at 6:17 AM Nikita Timofeev <nt...@objectstyle.com>
> wrote:
> 
>> Hi Lon,
>> 
>> The behavior you described in field-based objects seems normal
>> according to Cayenne own test case (see [1] for master branch and [2]
>> for 4.0 branch).
>> It should be like this in map-based objects too (i.e. no context and
>> no values inside). It is supposed that you attach object to context
>> manually after deserialization.
>> So unless you had some custom logic in map-based objects case, I
>> really don't know what is happening.
>> 
>> Maybe you can share your test case?
>> 
>> [1]
>> https://github.com/apache/cayenne/blob/master/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java#L129
>> [2]
>> https://github.com/apache/cayenne/blob/STABLE-4.0/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java#L129
>> 
>> On Thu, Feb 7, 2019 at 2:07 AM Lon Varscsak <lo...@gmail.com>
>> wrote:
>>> 
>>> Hey all,
>>> 
>>> Recently I switched to 4.1's field based data objects (I've been using
>>> 4/4.1 for a while, but using the Map based objects) and I ran into an
>>> issue.  It appears that when using this type of object, the
>>> de-serialization results in an object that is not usable.  It results in
>> a
>>> HOLLOW object that returns null for all of its values.  This object is
>> in a
>>> COMMITTED state to start (no changes), so it really shouldn't be doing
>>> anything special with serialization, but something is amiss.
>>> 
>>> To set the stage: So the object is called Site, it's PK is called siteId.
>>> I fetch an object, I then serialize that object (normally the web
>> framework
>>> would choose when to, but I've create some test code to verify this), I
>>> then deserialize the object.  Now when I call get*AnyAttribute*() on the
>>> deserialized Site object, they all return null and the object is HOLLOW.
>>> In the Map based template, the object is still hollow, but all of the
>>> properties will return a value.
>>> 
>>> Something else that really surprised me (just because of how long I've
>> been
>>> working with this code) is that the deserialized object in both cases no
>>> longer have an object context.  Not sure how I haven't encountered a
>>> problem with that before.
>>> 
>>> Any thoughts?
>>> 
>>> -Lon
>> 
>> 
>> 
>> --
>> Best regards,
>> Nikita Timofeev
>> 


Re: Cayenne and Serialization

Posted by Lon Varscsak <lo...@gmail.com>.
So reviving this topic (which is different than the one I just posted
separately), if I archive the DataContext myself along with the object, all
works as I'd expect (objectContext is not null and I get values back from
the object).  I guess I was just surprised that in the case of a Web
application, where the serialization of an object is outside my knowledge
(like when a framework might archive pages to save on memory) that I would
also have to remember to have a reference to (so it would also serialize)
the DataContext.  It happens that I almost always do, but sometimes one
might fetch some stuff with a context that they don't have a reference to
and would get this issue.

I'm sure there's a good explanation for this.

On Thu, Feb 7, 2019 at 6:17 AM Nikita Timofeev <nt...@objectstyle.com>
wrote:

> Hi Lon,
>
> The behavior you described in field-based objects seems normal
> according to Cayenne own test case (see [1] for master branch and [2]
> for 4.0 branch).
> It should be like this in map-based objects too (i.e. no context and
> no values inside). It is supposed that you attach object to context
> manually after deserialization.
> So unless you had some custom logic in map-based objects case, I
> really don't know what is happening.
>
> Maybe you can share your test case?
>
> [1]
> https://github.com/apache/cayenne/blob/master/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java#L129
> [2]
> https://github.com/apache/cayenne/blob/STABLE-4.0/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java#L129
>
> On Thu, Feb 7, 2019 at 2:07 AM Lon Varscsak <lo...@gmail.com>
> wrote:
> >
> > Hey all,
> >
> > Recently I switched to 4.1's field based data objects (I've been using
> > 4/4.1 for a while, but using the Map based objects) and I ran into an
> > issue.  It appears that when using this type of object, the
> > de-serialization results in an object that is not usable.  It results in
> a
> > HOLLOW object that returns null for all of its values.  This object is
> in a
> > COMMITTED state to start (no changes), so it really shouldn't be doing
> > anything special with serialization, but something is amiss.
> >
> > To set the stage: So the object is called Site, it's PK is called siteId.
> > I fetch an object, I then serialize that object (normally the web
> framework
> > would choose when to, but I've create some test code to verify this), I
> > then deserialize the object.  Now when I call get*AnyAttribute*() on the
> > deserialized Site object, they all return null and the object is HOLLOW.
> > In the Map based template, the object is still hollow, but all of the
> > properties will return a value.
> >
> > Something else that really surprised me (just because of how long I've
> been
> > working with this code) is that the deserialized object in both cases no
> > longer have an object context.  Not sure how I haven't encountered a
> > problem with that before.
> >
> > Any thoughts?
> >
> > -Lon
>
>
>
> --
> Best regards,
> Nikita Timofeev
>

Re: Cayenne and Serialization

Posted by Nikita Timofeev <nt...@objectstyle.com>.
Hi Lon,

The behavior you described in field-based objects seems normal
according to Cayenne own test case (see [1] for master branch and [2]
for 4.0 branch).
It should be like this in map-based objects too (i.e. no context and
no values inside). It is supposed that you attach object to context
manually after deserialization.
So unless you had some custom logic in map-based objects case, I
really don't know what is happening.

Maybe you can share your test case?

[1] https://github.com/apache/cayenne/blob/master/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java#L129
[2] https://github.com/apache/cayenne/blob/STABLE-4.0/cayenne-server/src/test/java/org/apache/cayenne/DataObjectSerializationIT.java#L129

On Thu, Feb 7, 2019 at 2:07 AM Lon Varscsak <lo...@gmail.com> wrote:
>
> Hey all,
>
> Recently I switched to 4.1's field based data objects (I've been using
> 4/4.1 for a while, but using the Map based objects) and I ran into an
> issue.  It appears that when using this type of object, the
> de-serialization results in an object that is not usable.  It results in a
> HOLLOW object that returns null for all of its values.  This object is in a
> COMMITTED state to start (no changes), so it really shouldn't be doing
> anything special with serialization, but something is amiss.
>
> To set the stage: So the object is called Site, it's PK is called siteId.
> I fetch an object, I then serialize that object (normally the web framework
> would choose when to, but I've create some test code to verify this), I
> then deserialize the object.  Now when I call get*AnyAttribute*() on the
> deserialized Site object, they all return null and the object is HOLLOW.
> In the Map based template, the object is still hollow, but all of the
> properties will return a value.
>
> Something else that really surprised me (just because of how long I've been
> working with this code) is that the deserialized object in both cases no
> longer have an object context.  Not sure how I haven't encountered a
> problem with that before.
>
> Any thoughts?
>
> -Lon



-- 
Best regards,
Nikita Timofeev