This is a migrated thread and some comments may be shown as answers.

Serializing Persistent Object

13 Answers 122 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Pål
Top achievements
Rank 1
Pål asked on 20 Oct 2011, 08:21 PM
Hi.

I'm trying to serialize/deserialize a persistent object using the method described here:
How to: Serialize and Deserialize Objects

Only difference is that I'm using a binary formatter instead of xml.

This seems to work fine for serialization, but fails on deserialization.

My class implements ISerializable and in GetObjectData() everything is executed as expected.
However, when the deserialization constructor(info, context) is called, my persistent collections have been changed into TrackedList<T>.

My Collection class contains lots of logic to handle the collection items, and this won't work when serialized/deserialized to another tier.

Save/Load of class handles this fine (as long as I declare the field as IList<MyClass> m_Classes = new MyClassCollection() (which inherits from TrackedList<T>).

Another thing that I noticed is that on serialization, the IInstanceCallBack.PostLoad() method is called on the same referene instance I'm serializing (cheked this using GetHasgCode()). I would expect this behaviour on de-serialization, but not on serialization.

Thanks

Pål

13 Answers, 1 is accepted

Sort by
0
Pål
Top achievements
Rank 1
answered on 21 Oct 2011, 09:51 AM
Hi.

Just another question. If I serialize persistent objects without the ObjectContainer, will the complete object graph be lazy-loaded as objects are added to SerializationInfo? Because this is definitively not what I want...

Thanks.

Pål
0
Zoran
Telerik team
answered on 25 Oct 2011, 03:29 PM
Hi Pål,

 When your public collection properties in your model are of type IList<T>, they are automatically treated as TrackedList<T> unless you are initializing them differently like you are doing. However during deserialization the properties are initialized differently and the default type for them is TrackedList<T>. If you want to change that, you should declare your properties as public MyClassCollection<T> YourCollectionProperty{get;set;}.

If the type of the public property is of your desired type you should have your properties initialized with that type after deserialization. 

As for the second question, no, the properties will not be lazily loaded and you will get only the primitive properties of your objects populated. The lazy loading will be triggered after you access the getter of some of the navigation properties.

Best wishes,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

0
Pål
Top achievements
Rank 1
answered on 26 Oct 2011, 08:09 AM
Hi again, and thank you for your reply.

The thing is that I'd like to declare my collection properties as you suggest (strong), but if I do that I run in to trouble with database load, as explained here:
Extending TrackedList

The solution to this was to declare collection field as IList<MyCollectionItem> items = new MyCustomCollection(); and cast field to MyCustomCollection in the property. This works fine and correct collection class is created when loaded from the database.

So if I declare the field strongly, I loose the collection type on database load, and if not I loose it on serialization.

The lazy load stuff is good news, though.

But i still am curious about the  IInstanceCallBack.PostLoad() method being called on serialization. On further reflection, I wouldn't expect this to be called on de-serialization either, as I know which constructor will be called and all the fields are already in place.

Please advice.

Thanks

Pål
0
Zoran
Telerik team
answered on 31 Oct 2011, 03:29 PM
Hello Pål,

 Is the IInstanceCallback.PostLoad() method called on the referenced entities or is it called on the instance that you are serializing? 

Also, calling PostLoad() on the serialized instance is expected if you have fetched the instance by id as the instance is fetched as Hollow, and the properties are loaded when the serializer executes serialization. Also the instance is marked as Hollow after transaction.Commit() has occurred so this could explain the behavior as well.

Best wishes,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

0
Pål
Top achievements
Rank 1
answered on 01 Nov 2011, 03:25 PM
Hi

The PostLoad function is called on the instance being serialized. This means it was called once when I retrieved the instance from the database and once again when I serialize it.

I do not believe this is correct behaviour.If anything, PostLoad could be called on the De-serialized instance, not the serialized one.

The object graph for the instance I'm serializing has been completely retrieved from the database. There are no hollow references at the time of serialization.

Thanks

Pål
0
Zoran
Telerik team
answered on 03 Nov 2011, 06:15 PM
Hello Pål,

 Unfortunately we have not been able to reproduce this behavior on our side. What we have double-checked though is that this method is being called only when persistent data is being fetched from the database. Can you send us a sample project where this behavior is reproduced, or maybe check with a database profiling tool about which fields are fetched when you perform serialization. 

This behavior can be triggered by loading of some internal fields in case you have some inheritance or using structs in the model.

Regards,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

0
Pål
Top achievements
Rank 1
answered on 04 Nov 2011, 10:05 AM
Hi.

I'll try too extract the code that's not working into a project and send it to you.

But the most important thing here is not the PostLoad, but the Deserialization of extended TrackedLists. I order to make them load correctly from database, the fields need to be declared as IList<>, but to correctly serialize/deserialize, you say they must be strongly typed.

So the way I see it, there is no way to do both, and I cannot se a workaround for this either.

What strikes me as odd though, is that the deserializer need to check the field declaration when deserializing. It should be irrelevant to the deserializer what kind of fields I have in my class. All the needed information is already in the SerializationInfo object:

info.Add("m_MyExtendedTrackedList", m_MyExtendedTrackedList, typeof(ExtendedTrackedList<MyClass>));

Thanks

Pål
0
Zoran
Telerik team
answered on 09 Nov 2011, 10:30 AM
Hi Pål,

 I prepared an example where serialization/deserialization does work as expected e.g. the type of the collection property on the object i serialize is correct after deserialization. I believe that the difference on your side might be that you collection property is not generic. If that is the case than I suggest you to try defining your collection as MyCustomCollection<T>.

I am sending you my example which you could use as a reference.

Kind regards,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

0
Zoran
Telerik team
answered on 09 Nov 2011, 10:30 AM
Hi Pål,

 I prepared an example where serialization/deserialization does work as expected e.g. the type of the collection property on the object i serialize is correct after deserialization. I believe that the difference on your side might be that you collection property is not generic. If that is the case than I suggest you to try defining your collection as MyCustomCollection<T>.

I am sending you my example which you could use as a reference.

Kind regards,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

0
Zoran
Telerik team
answered on 09 Nov 2011, 10:30 AM
Hi Pål,

 I prepared an example where serialization/deserialization does work as expected e.g. the type of the collection property on the object i serialize is correct after deserialization. I believe that the difference on your side might be that you collection property is not generic. If that is the case than I suggest you to try defining your collection as MyCustomCollection<T>.

I am sending you my example which you could use as a reference.

Kind regards,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

0
Pål
Top achievements
Rank 1
answered on 09 Nov 2011, 12:14 PM
Great, thanks. I'll have a look.

I believe I do both actually, but I have a base boilerplate collection class: abstract PersistentCollection<T> : TrackedList<T>

and then I use, say: public class OrderCollection : PersistentCollection<Order>.

I've also tried public class OrderCollection : TrackedList<Order>, but there is no difference in behaviour it the last two.

In any case, i'll look at your solution and make use that as reference.

Thanks

Pål
0
Pål
Top achievements
Rank 1
answered on 09 Nov 2011, 09:44 PM
Hi.

As beatuiful and simple as it looks, I'm afraid I'm a bit old-school when it comes to mapping, so I think I'll create a similar project using classic OpenAccess mapping and post that when ready.

Thanks.

Pål
0
Zoran
Telerik team
answered on 14 Nov 2011, 02:59 PM
Hello Pål,

 We are looking forward to see the results from your test case.

Best wishes,
Zoran
the Telerik team

NEW and UPDATED OpenAccess ORM Resources. Check them out!

Tags
Development (API, general questions)
Asked by
Pål
Top achievements
Rank 1
Answers by
Pål
Top achievements
Rank 1
Zoran
Telerik team
Share this question
or