Page 1 of 1

Deserialization error

PostPosted: Thu Aug 21, 2014 11:36 am
by BlackSoul
Hello.
I tryed to use xml serialize/deserialize feature and got a problem.
If I serialize objects to XML, change class api and try to deserialize it back, I get an assert(not just an error).
can i check it before deserialize?
Thank you.

Re: Deserialization error

PostPosted: Thu Aug 21, 2014 3:07 pm
by qxorm
Hello,

What do you mean exactly by "change class api" ?

There is a class version number available (by default, it is 0).
Each time you change a registered class (for example, adding a registered property), you have to increment this version number.

To have an example, just see the Quick Sample available on the website : http://www.qxorm.com/qxorm_en/quick_sample.html
- The line "QX_REGISTER_HPP_MY_TEST_EXE(drug, qx::trait::no_base_class_defined, 1)" with the comment "/* param 3 : the class version used by serialization to provide 'ascendant compatibility' */".
- And in the implementation, the line "t.data(& drug::name, "name", 1);" which means that the name property has been added in the version 1 of the class.

Re: Deserialization error

PostPosted: Thu Sep 04, 2014 6:25 am
by BlackSoul
Ok. if I added or changed some fields, it's really work.
But what can I do, if I need to remove obsolete field?

Re: Deserialization error

PostPosted: Thu Sep 04, 2014 7:08 am
by qxorm
if I need to remove obsolete field?

If you want to keep serialization ascendant compatibility, here is my advice :
- do not remove your data member in the C++ class ;
- do not remove the registration of this data member in the qx::register_class<T>() function ;
- remove getter/setter ==> this way, this field is obsolote and cannot be viewed outside the class.

Re: Deserialization error

PostPosted: Thu Sep 04, 2014 7:24 am
by BlackSoul
o_O
I don't want compatibility. I just want my app not crash.

Or I can't change db structure and must keep all garbage?

Re: Deserialization error

PostPosted: Thu Sep 04, 2014 8:53 am
by qxorm
I don't want compatibility. I just want my app not crash.

If you don't want app crash, then you have to manage serialization ascendant compatibility !

I can't change db structure and must keep all garbage?

On database side, you can remove the obsolete column.
And in the qx::dao::register_class<T>() function, just use the fifth parameter of the qx::QxClass<T>::data() method (bool bDao), something like this :
Code: Select all
namespace qx {
template <> void register_class(QxClass<myClass> & t)
{
  t.data(& myClass::myObsoleteProperty, "myObsoleteProperty", 0, true, false);
}}

Then remove getter/setter of this property in your C++ class : so the obsolete property is hidden outside the C++ class, and you have removed the obsolete column in database.

Note : QxEntityEditor can help you to manage ascendant compatibility and class/property version number :
- menu "Actions >> Tag project state" when you release a new version of your product for example ;
- and there is an "obsolete" field in the property params window.

Re: Deserialization error

PostPosted: Fri Sep 05, 2014 7:19 am
by BlackSoul
It's too difficult to maintain. many places, which developer must remember to change.
If app already in use, cost of mistake is very high.
Just commented ASSERT in QxArchive.inl and all works as I want.
Without support obsolete versions, without garbage and without crashes. =)

Re: Deserialization error

PostPosted: Fri Sep 05, 2014 9:36 am
by qxorm
It's too difficult to maintain. many places, which developer must remember to change.
If app already in use, cost of mistake is very high.

This is true for many (all ?) serialization/deserialization engine !
If you want to keep an ascendant compatibility between 2 versions of your product, you have to maintain a version number, and to take care adding/modifying/deleting properties.
And this is why QxEntityEditor can hep you to maintain an ascendant compatibility.

Just commented ASSERT in QxArchive.inl and all works as I want.
Without support obsolete versions, without garbage and without crashes. =)

Great but if there is an assert, it is because there is something wrong (in release mode, you don't care about assert => so no error in release mode).
So yes you can remove it if you prefer, but not sure your object is deserialized correctly.