Serializing Persistent Object

14 posts, 0 answers
  1. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 20 Oct 2011 Link to this post

    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

  2. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 21 Oct 2011 Link to this post

    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
  3. DevCraft banner
  4. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 25 Oct 2011 Link to this post

    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!

  5. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 26 Oct 2011 Link to this post

    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
  6. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 31 Oct 2011 Link to this post

    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!

  7. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 01 Nov 2011 Link to this post

    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
  8. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 03 Nov 2011 Link to this post

    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!

  9. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 04 Nov 2011 Link to this post

    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
  10. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 09 Nov 2011 Link to this post

    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!

  11. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 09 Nov 2011 Link to this post

    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!

  12. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 09 Nov 2011 Link to this post

    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!

  13. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 09 Nov 2011 Link to this post

    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
  14. Pål
    Pål avatar
    53 posts
    Member since:
    Sep 2012

    Posted 09 Nov 2011 Link to this post

    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
  15. Zoran
    Admin
    Zoran avatar
    534 posts

    Posted 14 Nov 2011 Link to this post

    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!

Back to Top
DevCraft banner